Merge commit 'v2.6.28-rc2' into tracing/urgent

This commit is contained in:
Ingo Molnar 2008-10-27 10:50:54 +01:00
commit 4944dd62de
1977 changed files with 98217 additions and 26454 deletions

11
CREDITS
View file

@ -598,6 +598,11 @@ S: Tamsui town, Taipei county,
S: Taiwan 251
S: Republic of China
N: Reinette Chatre
E: reinette.chatre@intel.com
D: WiMedia Link Protocol implementation
D: UWB stack bits and pieces
N: Michael Elizabeth Chastain
E: mec@shout.net
D: Configure, Menuconfig, xconfig
@ -2695,6 +2700,12 @@ S: Demonstratsii 8-382
S: Tula 300000
S: Russia
N: Inaky Perez-Gonzalez
E: inaky.perez-gonzalez@intel.com
D: UWB stack, HWA-RC driver and HWA-HC drivers
D: Wireless USB additions to the USB stack
D: WiMedia Link Protocol bits and pieces
N: Gordon Peters
E: GordPeters@smarttech.com
D: Isochronous receive for IEEE 1394 driver (OHCI module).

View file

@ -0,0 +1,28 @@
What: /sys/bus/umc/
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
The Wireless Host Controller Interface (WHCI)
specification describes a PCI-based device with
multiple capabilities; the UWB Multi-interface
Controller (UMC).
The umc bus presents each of the individual
capabilties as a device.
What: /sys/bus/umc/devices/.../capability_id
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
The ID of this capability, with 0 being the radio
controller capability.
What: /sys/bus/umc/devices/.../version
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
The specification version this capability's hardware
interface complies with.

View file

@ -101,3 +101,46 @@ Description:
Users:
USB PM tool
git://git.moblin.org/users/sarah/usb-pm-tool/
What: /sys/bus/usb/device/.../authorized
Date: July 2008
KernelVersion: 2.6.26
Contact: David Vrabel <david.vrabel@csr.com>
Description:
Authorized devices are available for use by device
drivers, non-authorized one are not. By default, wired
USB devices are authorized.
Certified Wireless USB devices are not authorized
initially and should be (by writing 1) after the
device has been authenticated.
What: /sys/bus/usb/device/.../wusb_cdid
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
For Certified Wireless USB devices only.
A devices's CDID, as 16 space-separated hex octets.
What: /sys/bus/usb/device/.../wusb_ck
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
For Certified Wireless USB devices only.
Write the device's connection key (CK) to start the
authentication of the device. The CK is 16
space-separated hex octets.
What: /sys/bus/usb/device/.../wusb_disconnect
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
For Certified Wireless USB devices only.
Write a 1 to force the device to disconnect
(equivalent to unplugging a wired USB device).

View file

@ -0,0 +1,25 @@
What: /sys/class/usb_host/usb_hostN/wusb_chid
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
Write the CHID (16 space-separated hex octets) for this host controller.
This starts the host controller, allowing it to accept connection from
WUSB devices.
Set an all zero CHID to stop the host controller.
What: /sys/class/usb_host/usb_hostN/wusb_trust_timeout
Date: July 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
Devices that haven't sent a WUSB packet to the host
within 'wusb_trust_timeout' ms are considered to have
disconnected and are removed. The default value of
4000 ms is the value required by the WUSB
specification.
Since this relates to security (specifically, the
lifetime of PTKs and GTKs) it should not be changed
from the default.

View file

@ -0,0 +1,144 @@
What: /sys/class/uwb_rc
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
Interfaces for WiMedia Ultra Wideband Common Radio
Platform (UWB) radio controllers.
Familiarity with the ECMA-368 'High Rate Ultra
Wideband MAC and PHY Specification' is assumed.
What: /sys/class/uwb_rc/beacon_timeout_ms
Date: July 2008
KernelVersion: 2.6.27
Description:
If no beacons are received from a device for at least
this time, the device will be considered to have gone
and it will be removed. The default is 3 superframes
(~197 ms) as required by the specification.
What: /sys/class/uwb_rc/uwbN/
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
An individual UWB radio controller.
What: /sys/class/uwb_rc/uwbN/beacon
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
Write:
<channel> [<bpst offset>]
to start beaconing on a specific channel, or stop
beaconing if <channel> is -1. Valid channels depends
on the radio controller's supported band groups.
<bpst offset> may be used to try and join a specific
beacon group if more than one was found during a scan.
What: /sys/class/uwb_rc/uwbN/scan
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
Write:
<channel> <type> [<bpst offset>]
to start (or stop) scanning on a channel. <type> is one of:
0 - scan
1 - scan outside BP
2 - scan while inactive
3 - scanning disabled
4 - scan (with start time of <bpst offset>)
What: /sys/class/uwb_rc/uwbN/mac_address
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
The EUI-48, in colon-separated hex octets, for this
radio controller. A write will change the radio
controller's EUI-48 but only do so while the device is
not beaconing or scanning.
What: /sys/class/uwb_rc/uwbN/wusbhc
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
A symlink to the device (if any) of the WUSB Host
Controller PAL using this radio controller.
What: /sys/class/uwb_rc/uwbN/<EUI-48>/
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
A neighbour UWB device that has either been detected
as part of a scan or is a member of the radio
controllers beacon group.
What: /sys/class/uwb_rc/uwbN/<EUI-48>/BPST
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
The time (using the radio controllers internal 1 ms
interval superframe timer) of the last beacon from
this device was received.
What: /sys/class/uwb_rc/uwbN/<EUI-48>/DevAddr
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
The current DevAddr of this device in colon separated
hex octets.
What: /sys/class/uwb_rc/uwbN/<EUI-48>/EUI_48
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
The EUI-48 of this device in colon separated hex
octets.
What: /sys/class/uwb_rc/uwbN/<EUI-48>/BPST
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
What: /sys/class/uwb_rc/uwbN/<EUI-48>/IEs
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
The latest IEs included in this device's beacon, in
space separated hex octets with one IE per line.
What: /sys/class/uwb_rc/uwbN/<EUI-48>/LQE
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
Link Quality Estimate - the Signal to Noise Ratio
(SNR) of all packets received from this device in dB.
This gives an estimate on a suitable PHY rate. Refer
to [ECMA-368] section 13.3 for more details.
What: /sys/class/uwb_rc/uwbN/<EUI-48>/RSSI
Date: July 2008
KernelVersion: 2.6.27
Contact: linux-usb@vger.kernel.org
Description:
Received Signal Strength Indication - the strength of
the received signal in dB. LQE is a more useful
measure of the radio link quality.

View file

@ -0,0 +1,100 @@
What: /sys/bus/usb/drivers/wusb_cbaf/.../wusb_*
Date: August 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
Various files for managing Cable Based Association of
(wireless) USB devices.
The sequence of operations should be:
1. Device is plugged in.
2. The connection manager (CM) sees a device with CBA capability.
(the wusb_chid etc. files in /sys/devices/blah/OURDEVICE).
3. The CM writes the host name, supported band groups,
and the CHID (host ID) into the wusb_host_name,
wusb_host_band_groups and wusb_chid files. These
get sent to the device and the CDID (if any) for
this host is requested.
4. The CM can verify that the device's supported band
groups (wusb_device_band_groups) are compatible
with the host.
5. The CM reads the wusb_cdid file.
6. The CM looks it up its database.
- If it has a matching CHID,CDID entry, the device
has been authorized before and nothing further
needs to be done.
- If the CDID is zero (or the CM doesn't find a
matching CDID in its database), the device is
assumed to be not known. The CM may associate
the host with device by: writing a randomly
generated CDID to wusb_cdid and then a random CK
to wusb_ck (this uploads the new CC to the
device).
CMD may choose to prompt the user before
associating with a new device.
7. Device is unplugged.
References:
[WUSB-AM] Association Models Supplement to the
Certified Wireless Universal Serial Bus
Specification, version 1.0.
What: /sys/bus/usb/drivers/wusb_cbaf/.../wusb_chid
Date: August 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
The CHID of the host formatted as 16 space-separated
hex octets.
Writes fetches device's supported band groups and the
the CDID for any existing association with this host.
What: /sys/bus/usb/drivers/wusb_cbaf/.../wusb_host_name
Date: August 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
A friendly name for the host as a UTF-8 encoded string.
What: /sys/bus/usb/drivers/wusb_cbaf/.../wusb_host_band_groups
Date: August 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
The band groups supported by the host, in the format
defined in [WUSB-AM].
What: /sys/bus/usb/drivers/wusb_cbaf/.../wusb_device_band_groups
Date: August 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
The band groups supported by the device, in the format
defined in [WUSB-AM].
What: /sys/bus/usb/drivers/wusb_cbaf/.../wusb_cdid
Date: August 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
The device's CDID formatted as 16 space-separated hex
octets.
What: /sys/bus/usb/drivers/wusb_cbaf/.../wusb_ck
Date: August 2008
KernelVersion: 2.6.27
Contact: David Vrabel <david.vrabel@csr.com>
Description:
Write 16 space-separated random, hex octets to
associate with the device.

View file

@ -359,3 +359,11 @@ Why: The 2.6 kernel supports direct writing to ide CD drives, which
eliminates the need for ide-scsi. The new method is more
efficient in every way.
Who: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
---------------------------
What: i2c_attach_client(), i2c_detach_client(), i2c_driver->detach_client()
When: 2.6.29 (ideally) or 2.6.30 (more likely)
Why: Deprecated by the new (standard) device driver binding model. Use
i2c_driver->probe() and ->remove() instead.
Who: Jean Delvare <khali@linux-fr.org>

View file

@ -8,7 +8,7 @@ Supported chips:
Datasheet: Publicly available at the National Semiconductor website
http://www.national.com/pf/LM/LM90.html
* National Semiconductor LM89
Prefix: 'lm99'
Prefix: 'lm89' (no auto-detection)
Addresses scanned: I2C 0x4c and 0x4d
Datasheet: Publicly available at the National Semiconductor website
http://www.national.com/mpf/LM/LM89.html

View file

@ -13,8 +13,9 @@ Supported adapters:
* Intel 631xESB/632xESB (ESB2)
* Intel 82801H (ICH8)
* Intel 82801I (ICH9)
* Intel Tolapai
* Intel ICH10
* Intel EP80579 (Tolapai)
* Intel 82801JI (ICH10)
* Intel PCH
Datasheets: Publicly available at the Intel website
Authors:
@ -32,7 +33,7 @@ Description
-----------
The ICH (properly known as the 82801AA), ICH0 (82801AB), ICH2 (82801BA),
ICH3 (82801CA/CAM) and later devices are Intel chips that are a part of
ICH3 (82801CA/CAM) and later devices (PCH) are Intel chips that are a part of
Intel's '810' chipset for Celeron-based PCs, '810E' chipset for
Pentium-based PCs, '815E' chipset, and others.

View file

@ -1,160 +0,0 @@
Revision 7, 2007-04-19
Jean Delvare <khali@linux-fr.org>
Greg KH <greg@kroah.com>
This is a guide on how to convert I2C chip drivers from Linux 2.4 to
Linux 2.6. I have been using existing drivers (lm75, lm78) as examples.
Then I converted a driver myself (lm83) and updated this document.
Note that this guide is strongly oriented towards hardware monitoring
drivers. Many points are still valid for other type of drivers, but
others may be irrelevant.
There are two sets of points below. The first set concerns technical
changes. The second set concerns coding policy. Both are mandatory.
Although reading this guide will help you porting drivers, I suggest
you keep an eye on an already ported driver while porting your own
driver. This will help you a lot understanding what this guide
exactly means. Choose the chip driver that is the more similar to
yours for best results.
Technical changes:
* [Driver type] Any driver that was relying on i2c-isa has to be
converted to a proper isa, platform or pci driver. This is not
covered by this guide.
* [Includes] Get rid of "version.h" and <linux/i2c-proc.h>.
Includes typically look like that:
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/hwmon.h> /* for hardware monitoring drivers */
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h> /* if you need VRM support */
#include <linux/err.h> /* for class registration */
Please respect this inclusion order. Some extra headers may be
required for a given driver (e.g. "lm75.h").
* [Addresses] SENSORS_I2C_END becomes I2C_CLIENT_END, ISA addresses
are no more handled by the i2c core. Address ranges are no more
supported either, define each individual address separately.
SENSORS_INSMOD_<n> becomes I2C_CLIENT_INSMOD_<n>.
* [Client data] Get rid of sysctl_id. Try using standard names for
register values (for example, temp_os becomes temp_max). You're
still relatively free here, but you *have* to follow the standard
names for sysfs files (see the Sysctl section below).
* [Function prototypes] The detect functions loses its flags
parameter. Sysctl (e.g. lm75_temp) and miscellaneous functions
are off the list of prototypes. This usually leaves five
prototypes:
static int lm75_attach_adapter(struct i2c_adapter *adapter);
static int lm75_detect(struct i2c_adapter *adapter, int address,
int kind);
static void lm75_init_client(struct i2c_client *client);
static int lm75_detach_client(struct i2c_client *client);
static struct lm75_data lm75_update_device(struct device *dev);
* [Sysctl] All sysctl stuff is of course gone (defines, ctl_table
and functions). Instead, you have to define show and set functions for
each sysfs file. Only define set for writable values. Take a look at an
existing 2.6 driver for details (it87 for example). Don't forget
to define the attributes for each file (this is that step that
links callback functions). Use the file names specified in
Documentation/hwmon/sysfs-interface for the individual files. Also
convert the units these files read and write to the specified ones.
If you need to add a new type of file, please discuss it on the
sensors mailing list <lm-sensors@lm-sensors.org> by providing a
patch to the Documentation/hwmon/sysfs-interface file.
* [Attach] The attach function should make sure that the adapter's
class has I2C_CLASS_HWMON (or whatever class is suitable for your
driver), using the following construct:
if (!(adapter->class & I2C_CLASS_HWMON))
return 0;
Call i2c_probe() instead of i2c_detect().
* [Detect] As mentioned earlier, the flags parameter is gone.
The type_name and client_name strings are replaced by a single
name string, which will be filled with a lowercase, short string.
The labels used for error paths are reduced to the number needed.
It is advised that the labels are given descriptive names such as
exit and exit_free. Don't forget to properly set err before
jumping to error labels. By the way, labels should be left-aligned.
Use kzalloc instead of kmalloc.
Use i2c_set_clientdata to set the client data (as opposed to
a direct access to client->data).
Use strlcpy instead of strcpy or snprintf to copy the client name.
Replace the sysctl directory registration by calls to
device_create_file. Move the driver initialization before any
sysfs file creation.
Register the client with the hwmon class (using hwmon_device_register)
if applicable.
Drop client->id.
Drop any 24RF08 corruption prevention you find, as this is now done
at the i2c-core level, and doing it twice voids it.
Don't add I2C_CLIENT_ALLOW_USE to client->flags, it's the default now.
* [Init] Limits must not be set by the driver (can be done later in
user-space). Chip should not be reset default (although a module
parameter may be used to force it), and initialization should be
limited to the strictly necessary steps.
* [Detach] Remove the call to i2c_deregister_entry. Do not log an
error message if i2c_detach_client fails, as i2c-core will now do
it for you.
Unregister from the hwmon class if applicable.
* [Update] The function prototype changed, it is now
passed a device structure, which you have to convert to a client
using to_i2c_client(dev). The update function should return a
pointer to the client data.
Don't access client->data directly, use i2c_get_clientdata(client)
instead.
Use time_after() instead of direct jiffies comparison.
* [Interface] Make sure there is a MODULE_LICENSE() line, at the bottom
of the file (after MODULE_AUTHOR() and MODULE_DESCRIPTION(), in this
order).
* [Driver] The flags field of the i2c_driver structure is gone.
I2C_DF_NOTIFY is now the default behavior.
The i2c_driver structure has a driver member, which is itself a
structure, those name member should be initialized to a driver name
string. i2c_driver itself has no name member anymore.
* [Driver model] Instead of shutdown or reboot notifiers, provide a
shutdown() method in your driver.
* [Power management] Use the driver model suspend() and resume()
callbacks instead of the obsolete pm_register() calls.
Coding policy:
* [Copyright] Use (C), not (c), for copyright.
* [Debug/log] Get rid of #ifdef DEBUG/#endif constructs whenever you
can. Calls to printk for debugging purposes are replaced by calls to
dev_dbg where possible, else to pr_debug. Here is an example of how
to call it (taken from lm75_detect):
dev_dbg(&client->dev, "Starting lm75 update\n");
Replace other printk calls with the dev_info, dev_err or dev_warn
function, as appropriate.
* [Constants] Constants defines (registers, conversions) should be
aligned. This greatly improves readability.
Alignments are achieved by the means of tabs, not spaces. Remember
that tabs are set to 8 in the Linux kernel code.
* [Layout] Avoid extra empty lines between comments and what they
comment. Respect the coding style (see Documentation/CodingStyle),
in particular when it comes to placing curly braces.
* [Comments] Make sure that no comment refers to a file that isn't
part of the Linux source tree (typically doc/chips/<chip name>),
and that remaining comments still match the code. Merging comment
lines when possible is encouraged.

View file

@ -10,23 +10,21 @@ General remarks
===============
Try to keep the kernel namespace as clean as possible. The best way to
do this is to use a unique prefix for all global symbols. This is
do this is to use a unique prefix for all global symbols. This is
especially important for exported symbols, but it is a good idea to do
it for non-exported symbols too. We will use the prefix `foo_' in this
tutorial, and `FOO_' for preprocessor variables.
tutorial.
The driver structure
====================
Usually, you will implement a single driver structure, and instantiate
all clients from it. Remember, a driver structure contains general access
all clients from it. Remember, a driver structure contains general access
routines, and should be zero-initialized except for fields with data you
provide. A client structure holds device-specific information like the
driver model device node, and its I2C address.
/* iff driver uses driver model ("new style") binding model: */
static struct i2c_device_id foo_idtable[] = {
{ "foo", my_id_for_foo },
{ "bar", my_id_for_bar },
@ -40,7 +38,6 @@ static struct i2c_driver foo_driver = {
.name = "foo",
},
/* iff driver uses driver model ("new style") binding model: */
.id_table = foo_ids,
.probe = foo_probe,
.remove = foo_remove,
@ -49,24 +46,19 @@ static struct i2c_driver foo_driver = {
.detect = foo_detect,
.address_data = &addr_data,
/* else, driver uses "legacy" binding model: */
.attach_adapter = foo_attach_adapter,
.detach_client = foo_detach_client,
/* these may be used regardless of the driver binding model */
.shutdown = foo_shutdown, /* optional */
.suspend = foo_suspend, /* optional */
.resume = foo_resume, /* optional */
.command = foo_command, /* optional */
.command = foo_command, /* optional, deprecated */
}
The name field is the driver name, and must not contain spaces. It
should match the module name (if the driver can be compiled as a module),
although you can use MODULE_ALIAS (passing "foo" in this example) to add
another name for the module. If the driver name doesn't match the module
name, the module won't be automatically loaded (hotplug/coldplug).
All other fields are for call-back functions which will be explained
All other fields are for call-back functions which will be explained
below.
@ -74,34 +66,13 @@ Extra client data
=================
Each client structure has a special `data' field that can point to any
structure at all. You should use this to keep device-specific data,
especially in drivers that handle multiple I2C or SMBUS devices. You
do not always need this, but especially for `sensors' drivers, it can
be very useful.
structure at all. You should use this to keep device-specific data.
/* store the value */
void i2c_set_clientdata(struct i2c_client *client, void *data);
/* retrieve the value */
void *i2c_get_clientdata(struct i2c_client *client);
An example structure is below.
struct foo_data {
struct i2c_client client;
enum chips type; /* To keep the chips type for `sensors' drivers. */
/* Because the i2c bus is slow, it is often useful to cache the read
information of a chip for some time (for example, 1 or 2 seconds).
It depends of course on the device whether this is really worthwhile
or even sensible. */
struct mutex update_lock; /* When we are reading lots of information,
another process should not update the
below information */
char valid; /* != 0 if the following fields are valid. */
unsigned long last_updated; /* In jiffies */
/* Add the read information here too */
};
void *i2c_get_clientdata(const struct i2c_client *client);
Accessing the client
@ -109,11 +80,9 @@ Accessing the client
Let's say we have a valid client structure. At some time, we will need
to gather information from the client, or write new information to the
client. How we will export this information to user-space is less
important at this moment (perhaps we do not need to do this at all for
some obscure clients). But we need generic reading and writing routines.
client.
I have found it useful to define foo_read and foo_write function for this.
I have found it useful to define foo_read and foo_write functions for this.
For some cases, it will be easier to call the i2c functions directly,
but many chips have some kind of register-value idea that can easily
be encapsulated.
@ -121,33 +90,33 @@ be encapsulated.
The below functions are simple examples, and should not be copied
literally.
int foo_read_value(struct i2c_client *client, u8 reg)
{
if (reg < 0x10) /* byte-sized register */
return i2c_smbus_read_byte_data(client,reg);
else /* word-sized register */
return i2c_smbus_read_word_data(client,reg);
}
int foo_read_value(struct i2c_client *client, u8 reg)
{
if (reg < 0x10) /* byte-sized register */
return i2c_smbus_read_byte_data(client, reg);
else /* word-sized register */
return i2c_smbus_read_word_data(client, reg);
}
int foo_write_value(struct i2c_client *client, u8 reg, u16 value)
{
if (reg == 0x10) /* Impossible to write - driver error! */ {
return -1;
else if (reg < 0x10) /* byte-sized register */
return i2c_smbus_write_byte_data(client,reg,value);
else /* word-sized register */
return i2c_smbus_write_word_data(client,reg,value);
}
int foo_write_value(struct i2c_client *client, u8 reg, u16 value)
{
if (reg == 0x10) /* Impossible to write - driver error! */
return -EINVAL;
else if (reg < 0x10) /* byte-sized register */
return i2c_smbus_write_byte_data(client, reg, value);
else /* word-sized register */
return i2c_smbus_write_word_data(client, reg, value);
}
Probing and attaching
=====================
The Linux I2C stack was originally written to support access to hardware
monitoring chips on PC motherboards, and thus it embeds some assumptions
that are more appropriate to SMBus (and PCs) than to I2C. One of these
assumptions is that most adapters and devices drivers support the SMBUS_QUICK
protocol to probe device presence. Another is that devices and their drivers
monitoring chips on PC motherboards, and thus used to embed some assumptions
that were more appropriate to SMBus (and PCs) than to I2C. One of these
assumptions was that most adapters and devices drivers support the SMBUS_QUICK
protocol to probe device presence. Another was that devices and their drivers
can be sufficiently configured using only such probe primitives.
As Linux and its I2C stack became more widely used in embedded systems
@ -164,6 +133,9 @@ since the "legacy" model requires drivers to create "i2c_client" device
objects after SMBus style probing, while the Linux driver model expects
drivers to be given such device objects in their probe() routines.
The legacy model is deprecated now and will soon be removed, so we no
longer document it here.
Standard Driver Model Binding ("New Style")
-------------------------------------------
@ -193,8 +165,8 @@ matches the device's name. It is passed the entry that was matched so
the driver knows which one in the table matched.
Device Creation (Standard driver model)
---------------------------------------
Device Creation
---------------
If you know for a fact that an I2C device is connected to a given I2C bus,
you can instantiate that device by simply filling an i2c_board_info
@ -221,8 +193,8 @@ in the I2C bus driver. You may want to save the returned i2c_client
reference for later use.
Device Detection (Standard driver model)
----------------------------------------
Device Detection
----------------
Sometimes you do not know in advance which I2C devices are connected to
a given I2C bus. This is for example the case of hardware monitoring
@ -246,8 +218,8 @@ otherwise misdetections are likely to occur and things can get wrong
quickly.
Device Deletion (Standard driver model)
---------------------------------------
Device Deletion
---------------
Each I2C device which has been created using i2c_new_device() or
i2c_new_probed_device() can be unregistered by calling
@ -256,264 +228,37 @@ called automatically before the underlying I2C bus itself is removed, as a
device can't survive its parent in the device driver model.
Legacy Driver Binding Model
---------------------------
Initializing the driver
=======================
Most i2c devices can be present on several i2c addresses; for some this
is determined in hardware (by soldering some chip pins to Vcc or Ground),
for others this can be changed in software (by writing to specific client
registers). Some devices are usually on a specific address, but not always;
and some are even more tricky. So you will probably need to scan several
i2c addresses for your clients, and do some sort of detection to see
whether it is actually a device supported by your driver.
When the kernel is booted, or when your foo driver module is inserted,
you have to do some initializing. Fortunately, just registering the
driver module is usually enough.
To give the user a maximum of possibilities, some default module parameters
are defined to help determine what addresses are scanned. Several macros
are defined in i2c.h to help you support them, as well as a generic
detection algorithm.
static int __init foo_init(void)
{
return i2c_add_driver(&foo_driver);
}
You do not have to use this parameter interface; but don't try to use
function i2c_probe() if you don't.
static void __exit foo_cleanup(void)
{
i2c_del_driver(&foo_driver);
}
/* Substitute your own name and email address */
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"
MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices");
Probing classes (Legacy model)
------------------------------
/* a few non-GPL license types are also allowed */
MODULE_LICENSE("GPL");
All parameters are given as lists of unsigned 16-bit integers. Lists are
terminated by I2C_CLIENT_END.
The following lists are used internally:
module_init(foo_init);
module_exit(foo_cleanup);
normal_i2c: filled in by the module writer.
A list of I2C addresses which should normally be examined.
probe: insmod parameter.
A list of pairs. The first value is a bus number (-1 for any I2C bus),
the second is the address. These addresses are also probed, as if they
were in the 'normal' list.
ignore: insmod parameter.
A list of pairs. The first value is a bus number (-1 for any I2C bus),
the second is the I2C address. These addresses are never probed.
This parameter overrules the 'normal_i2c' list only.
force: insmod parameter.
A list of pairs. The first value is a bus number (-1 for any I2C bus),
the second is the I2C address. A device is blindly assumed to be on
the given address, no probing is done.
Additionally, kind-specific force lists may optionally be defined if
the driver supports several chip kinds. They are grouped in a
NULL-terminated list of pointers named forces, those first element if the
generic force list mentioned above. Each additional list correspond to an
insmod parameter of the form force_<kind>.
Fortunately, as a module writer, you just have to define the `normal_i2c'
parameter. The complete declaration could look like this:
/* Scan 0x4c to 0x4f */
static const unsigned short normal_i2c[] = { 0x4c, 0x4d, 0x4e, 0x4f,
I2C_CLIENT_END };
/* Magic definition of all other variables and things */
I2C_CLIENT_INSMOD;
/* Or, if your driver supports, say, 2 kind of devices: */
I2C_CLIENT_INSMOD_2(foo, bar);
If you use the multi-kind form, an enum will be defined for you:
enum chips { any_chip, foo, bar, ... }
You can then (and certainly should) use it in the driver code.
Note that you *have* to call the defined variable `normal_i2c',
without any prefix!
Attaching to an adapter (Legacy model)
--------------------------------------
Whenever a new adapter is inserted, or for all adapters if the driver is
being registered, the callback attach_adapter() is called. Now is the
time to determine what devices are present on the adapter, and to register
a client for each of them.
The attach_adapter callback is really easy: we just call the generic
detection function. This function will scan the bus for us, using the
information as defined in the lists explained above. If a device is
detected at a specific address, another callback is called.
int foo_attach_adapter(struct i2c_adapter *adapter)
{
return i2c_probe(adapter,&addr_data,&foo_detect_client);
}
Remember, structure `addr_data' is defined by the macros explained above,
so you do not have to define it yourself.
The i2c_probe function will call the foo_detect_client
function only for those i2c addresses that actually have a device on
them (unless a `force' parameter was used). In addition, addresses that
are already in use (by some other registered client) are skipped.
The detect client function (Legacy model)
-----------------------------------------
The detect client function is called by i2c_probe. The `kind' parameter
contains -1 for a probed detection, 0 for a forced detection, or a positive
number for a forced detection with a chip type forced.
Returning an error different from -ENODEV in a detect function will cause
the detection to stop: other addresses and adapters won't be scanned.
This should only be done on fatal or internal errors, such as a memory
shortage or i2c_attach_client failing.
For now, you can ignore the `flags' parameter. It is there for future use.
int foo_detect_client(struct i2c_adapter *adapter, int address,
int kind)
{
int err = 0;
int i;
struct i2c_client *client;
struct foo_data *data;
const char *name = "";
/* Let's see whether this adapter can support what we need.
Please substitute the things you need here! */
if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA |
I2C_FUNC_SMBUS_WRITE_BYTE))
goto ERROR0;
/* OK. For now, we presume we have a valid client. We now create the
client structure, even though we cannot fill it completely yet.
But it allows us to access several i2c functions safely */
if (!(data = kzalloc(sizeof(struct foo_data), GFP_KERNEL))) {
err = -ENOMEM;
goto ERROR0;
}
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &foo_driver;
/* Now, we do the remaining detection. If no `force' parameter is used. */
/* First, the generic detection (if any), that is skipped if any force
parameter was used. */
if (kind < 0) {
/* The below is of course bogus */
if (foo_read(client, FOO_REG_GENERIC) != FOO_GENERIC_VALUE)
goto ERROR1;
}
/* Next, specific detection. This is especially important for `sensors'
devices. */
/* Determine the chip type. Not needed if a `force_CHIPTYPE' parameter
was used. */
if (kind <= 0) {
i = foo_read(client, FOO_REG_CHIPTYPE);
if (i == FOO_TYPE_1)
kind = chip1; /* As defined in the enum */
else if (i == FOO_TYPE_2)
kind = chip2;
else {
printk("foo: Ignoring 'force' parameter for unknown chip at "
"adapter %d, address 0x%02x\n",i2c_adapter_id(adapter),address);
goto ERROR1;
}
}
/* Now set the type and chip names */
if (kind == chip1) {
name = "chip1";
} else if (kind == chip2) {
name = "chip2";
}
/* Fill in the remaining client fields. */
strlcpy(client->name, name, I2C_NAME_SIZE);
data->type = kind;
mutex_init(&data->update_lock); /* Only if you use this field */
/* Any other initializations in data must be done here too. */
/* This function can write default values to the client registers, if
needed. */
foo_init_client(client);
/* Tell the i2c layer a new client has arrived */
if ((err = i2c_attach_client(client)))
goto ERROR1;
return 0;
/* OK, this is not exactly good programming practice, usually. But it is
very code-efficient in this case. */
ERROR1:
kfree(data);
ERROR0:
return err;
}
Removing the client (Legacy model)
==================================
The detach_client call back function is called when a client should be
removed. It may actually fail, but only when panicking. This code is
much simpler than the attachment code, fortunately!
int foo_detach_client(struct i2c_client *client)
{
int err;
/* Try to detach the client from i2c space */
if ((err = i2c_detach_client(client)))
return err;
kfree(i2c_get_clientdata(client));
return 0;
}
Initializing the module or kernel
=================================
When the kernel is booted, or when your foo driver module is inserted,
you have to do some initializing. Fortunately, just attaching (registering)
the driver module is usually enough.
static int __init foo_init(void)
{
int res;
if ((res = i2c_add_driver(&foo_driver))) {
printk("foo: Driver registration failed, module not inserted.\n");
return res;
}
return 0;
}
static void __exit foo_cleanup(void)
{
i2c_del_driver(&foo_driver);
}
/* Substitute your own name and email address */
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"
MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices");
/* a few non-GPL license types are also allowed */
MODULE_LICENSE("GPL");
module_init(foo_init);
module_exit(foo_cleanup);
Note that some functions are marked by `__init', and some data structures
by `__initdata'. These functions and structures can be removed after
kernel booting (or module loading) is completed.
Note that some functions are marked by `__init'. These functions can
be removed after kernel booting (or module loading) is completed.
Likewise, functions marked by `__exit' are dropped by the compiler when
the code is built into the kernel, as they would never be called.
Power Management
@ -548,33 +293,35 @@ Command function
A generic ioctl-like function call back is supported. You will seldom
need this, and its use is deprecated anyway, so newer design should not
use it. Set it to NULL.
use it.
Sending and receiving
=====================
If you want to communicate with your device, there are several functions
to do this. You can find all of them in i2c.h.
to do this. You can find all of them in <linux/i2c.h>.
If you can choose between plain i2c communication and SMBus level
communication, please use the last. All adapters understand SMBus level
commands, but only some of them understand plain i2c!
If you can choose between plain I2C communication and SMBus level
communication, please use the latter. All adapters understand SMBus level
commands, but only some of them understand plain I2C!
Plain i2c communication
Plain I2C communication
-----------------------
extern int i2c_master_send(struct i2c_client *,const char* ,int);
extern int i2c_master_recv(struct i2c_client *,char* ,int);
int i2c_master_send(struct i2c_client *client, const char *buf,
int count);
int i2c_master_recv(struct i2c_client *client, char *buf, int count);
These routines read and write some bytes from/to a client. The client
contains the i2c address, so you do not have to include it. The second
parameter contains the bytes the read/write, the third the length of the
buffer. Returned is the actual number of bytes read/written.
extern int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msg,
int num);
parameter contains the bytes to read/write, the third the number of bytes
to read/write (must be less than the length of the buffer.) Returned is
the actual number of bytes read/written.
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msg,
int num);
This sends a series of messages. Each message can be a read or write,
and they can be mixed in any way. The transactions are combined: no
@ -583,49 +330,45 @@ for each message the client address, the number of bytes of the message
and the message data itself.
You can read the file `i2c-protocol' for more information about the
actual i2c protocol.
actual I2C protocol.
SMBus communication
-------------------
extern s32 i2c_smbus_xfer (struct i2c_adapter * adapter, u16 addr,
unsigned short flags,
char read_write, u8 command, int size,
union i2c_smbus_data * data);
s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr,
unsigned short flags, char read_write, u8 command,
int size, union i2c_smbus_data *data);
This is the generic SMBus function. All functions below are implemented
in terms of it. Never use this function directly!
This is the generic SMBus function. All functions below are implemented
in terms of it. Never use this function directly!
extern s32 i2c_smbus_read_byte(struct i2c_client * client);
extern s32 i2c_smbus_write_byte(struct i2c_client * client, u8 value);
extern s32 i2c_smbus_read_byte_data(struct i2c_client * client, u8 command);
extern s32 i2c_smbus_write_byte_data(struct i2c_client * client,
u8 command, u8 value);
extern s32 i2c_smbus_read_word_data(struct i2c_client * client, u8 command);
extern s32 i2c_smbus_write_word_data(struct i2c_client * client,
u8 command, u16 value);
extern s32 i2c_smbus_process_call(struct i2c_client *client,
u8 command, u16 value);
extern s32 i2c_smbus_read_block_data(struct i2c_client * client,
u8 command, u8 *values);
extern s32 i2c_smbus_write_block_data(struct i2c_client * client,
u8 command, u8 length,
u8 *values);
extern s32 i2c_smbus_read_i2c_block_data(struct i2c_client * client,
u8 command, u8 length, u8 *values);
extern s32 i2c_smbus_write_i2c_block_data(struct i2c_client * client,
u8 command, u8 length,
u8 *values);
s32 i2c_smbus_read_byte(struct i2c_client *client);
s32 i2c_smbus_write_byte(struct i2c_client *client, u8 value);
s32 i2c_smbus_read_byte_data(struct i2c_client *client, u8 command);
s32 i2c_smbus_write_byte_data(struct i2c_client *client,
u8 command, u8 value);
s32 i2c_smbus_read_word_data(struct i2c_client *client, u8 command);
s32 i2c_smbus_write_word_data(struct i2c_client *client,
u8 command, u16 value);
s32 i2c_smbus_process_call(struct i2c_client *client,
u8 command, u16 value);
s32 i2c_smbus_read_block_data(struct i2c_client *client,
u8 command, u8 *values);
s32 i2c_smbus_write_block_data(struct i2c_client *client,
u8 command, u8 length, const u8 *values);
s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client,
u8 command, u8 length, u8 *values);
s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client,
u8 command, u8 length,
const u8 *values);
These ones were removed from i2c-core because they had no users, but could
be added back later if needed:
extern s32 i2c_smbus_write_quick(struct i2c_client * client, u8 value);
extern s32 i2c_smbus_block_process_call(struct i2c_client *client,
u8 command, u8 length,
u8 *values)
s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value);
s32 i2c_smbus_block_process_call(struct i2c_client *client,
u8 command, u8 length, u8 *values);
All these transactions return a negative errno value on failure. The 'write'
transactions return 0 on success; the 'read' transactions return the read
@ -642,7 +385,5 @@ General purpose routines
Below all general purpose routines are listed, that were not mentioned
before.
/* This call returns a unique low identifier for each registered adapter.
*/
extern int i2c_adapter_id(struct i2c_adapter *adap);
/* Return the adapter number for a specific adapter */
int i2c_adapter_id(struct i2c_adapter *adap);

183
Documentation/ia64/xen.txt Normal file
View file

@ -0,0 +1,183 @@
Recipe for getting/building/running Xen/ia64 with pv_ops
--------------------------------------------------------
This recipe describes how to get xen-ia64 source and build it,
and run domU with pv_ops.
============
Requirements
============
- python
- mercurial
it (aka "hg") is an open-source source code
management software. See the below.
http://www.selenic.com/mercurial/wiki/
- git
- bridge-utils
=================================
Getting and Building Xen and Dom0
=================================
My environment is;
Machine : Tiger4
Domain0 OS : RHEL5
DomainU OS : RHEL5
1. Download source
# hg clone http://xenbits.xensource.com/ext/ia64/xen-unstable.hg
# cd xen-unstable.hg
# hg clone http://xenbits.xensource.com/ext/ia64/linux-2.6.18-xen.hg
2. # make world
3. # make install-tools
4. copy kernels and xen
# cp xen/xen.gz /boot/efi/efi/redhat/
# cp build-linux-2.6.18-xen_ia64/vmlinux.gz \
/boot/efi/efi/redhat/vmlinuz-2.6.18.8-xen
5. make initrd for Dom0/DomU
# make -C linux-2.6.18-xen.hg ARCH=ia64 modules_install \
O=$(/bin/pwd)/build-linux-2.6.18-xen_ia64
# mkinitrd -f /boot/efi/efi/redhat/initrd-2.6.18.8-xen.img \
2.6.18.8-xen --builtin mptspi --builtin mptbase \
--builtin mptscsih --builtin uhci-hcd --builtin ohci-hcd \
--builtin ehci-hcd
================================
Making a disk image for guest OS
================================
1. make file
# dd if=/dev/zero of=/root/rhel5.img bs=1M seek=4096 count=0
# mke2fs -F -j /root/rhel5.img
# mount -o loop /root/rhel5.img /mnt
# cp -ax /{dev,var,etc,usr,bin,sbin,lib} /mnt
# mkdir /mnt/{root,proc,sys,home,tmp}
Note: You may miss some device files. If so, please create them
with mknod. Or you can use tar instead of cp.
2. modify DomU's fstab
# vi /mnt/etc/fstab
/dev/xvda1 / ext3 defaults 1 1
none /dev/pts devpts gid=5,mode=620 0 0
none /dev/shm tmpfs defaults 0 0
none /proc proc defaults 0 0
none /sys sysfs defaults 0 0
3. modify inittab
set runlevel to 3 to avoid X trying to start
# vi /mnt/etc/inittab
id:3:initdefault:
Start a getty on the hvc0 console
X0:2345:respawn:/sbin/mingetty hvc0
tty1-6 mingetty can be commented out
4. add hvc0 into /etc/securetty
# vi /mnt/etc/securetty (add hvc0)
5. umount
# umount /mnt
FYI, virt-manager can also make a disk image for guest OS.
It's GUI tools and easy to make it.
==================
Boot Xen & Domain0
==================
1. replace elilo
elilo of RHEL5 can boot Xen and Dom0.
If you use old elilo (e.g RHEL4), please download from the below
http://elilo.sourceforge.net/cgi-bin/blosxom
and copy into /boot/efi/efi/redhat/
# cp elilo-3.6-ia64.efi /boot/efi/efi/redhat/elilo.efi
2. modify elilo.conf (like the below)
# vi /boot/efi/efi/redhat/elilo.conf
prompt
timeout=20
default=xen
relocatable
image=vmlinuz-2.6.18.8-xen
label=xen
vmm=xen.gz
initrd=initrd-2.6.18.8-xen.img
read-only
append=" -- rhgb root=/dev/sda2"
The append options before "--" are for xen hypervisor,
the options after "--" are for dom0.
FYI, your machine may need console options like
"com1=19200,8n1 console=vga,com1". For example,
append="com1=19200,8n1 console=vga,com1 -- rhgb console=tty0 \
console=ttyS0 root=/dev/sda2"
=====================================
Getting and Building domU with pv_ops
=====================================
1. get pv_ops tree
# git clone http://people.valinux.co.jp/~yamahata/xen-ia64/linux-2.6-xen-ia64.git/
2. git branch (if necessary)
# cd linux-2.6-xen-ia64/
# git checkout -b your_branch origin/xen-ia64-domu-minimal-2008may19
(Note: The current branch is xen-ia64-domu-minimal-2008may19.
But you would find the new branch. You can see with
"git branch -r" to get the branch lists.
http://people.valinux.co.jp/~yamahata/xen-ia64/for_eagl/linux-2.6-ia64-pv-ops.git/
is also available. The tree is based on
git://git.kernel.org/pub/scm/linux/kernel/git/aegl/linux-2.6 test)
3. copy .config for pv_ops of domU
# cp arch/ia64/configs/xen_domu_wip_defconfig .config
4. make kernel with pv_ops
# make oldconfig
# make
5. install the kernel and initrd
# cp vmlinux.gz /boot/efi/efi/redhat/vmlinuz-2.6-pv_ops-xenU
# make modules_install
# mkinitrd -f /boot/efi/efi/redhat/initrd-2.6-pv_ops-xenU.img \
2.6.26-rc3xen-ia64-08941-g1b12161 --builtin mptspi \
--builtin mptbase --builtin mptscsih --builtin uhci-hcd \
--builtin ohci-hcd --builtin ehci-hcd
========================
Boot DomainU with pv_ops
========================
1. make config of DomU
# vi /etc/xen/rhel5
kernel = "/boot/efi/efi/redhat/vmlinuz-2.6-pv_ops-xenU"
ramdisk = "/boot/efi/efi/redhat/initrd-2.6-pv_ops-xenU.img"
vcpus = 1
memory = 512
name = "rhel5"
disk = [ 'file:/root/rhel5.img,xvda1,w' ]
root = "/dev/xvda1 ro"
extra= "rhgb console=hvc0"
2. After boot xen and dom0, start xend
# /etc/init.d/xend start
( In the debugging case, # XEND_DEBUG=1 xend trace_start )
3. start domU
# xm create -c rhel5
=========
Reference
=========
- Wiki of Xen/IA64 upstream merge
http://wiki.xensource.com/xenwiki/XenIA64/UpstreamMerge
Written by Akio Takebe <takebe_akio@jp.fujitsu.com> on 28 May 2008

View file

@ -109,7 +109,8 @@ There are two possible methods of using Kdump.
2) Or use the system kernel binary itself as dump-capture kernel and there is
no need to build a separate dump-capture kernel. This is possible
only with the architecutres which support a relocatable kernel. As
of today, i386, x86_64 and ia64 architectures support relocatable kernel.
of today, i386, x86_64, ppc64 and ia64 architectures support relocatable
kernel.
Building a relocatable kernel is advantageous from the point of view that
one does not have to build a second kernel for capturing the dump. But
@ -207,8 +208,15 @@ Dump-capture kernel config options (Arch Dependent, i386 and x86_64)
Dump-capture kernel config options (Arch Dependent, ppc64)
----------------------------------------------------------
* Make and install the kernel and its modules. DO NOT add this kernel
to the boot loader configuration files.
1) Enable "Build a kdump crash kernel" support under "Kernel" options:
CONFIG_CRASH_DUMP=y
2) Enable "Build a relocatable kernel" support
CONFIG_RELOCATABLE=y
Make and install the kernel and its modules.
Dump-capture kernel config options (Arch Dependent, ia64)
----------------------------------------------------------

View file

@ -218,20 +218,47 @@ and is between 256 and 4096 characters. It is defined in the file
acpi.debug_level= [HW,ACPI]
Format: <int>
Each bit of the <int> indicates an ACPI debug level,
1: enable, 0: disable. It is useful for boot time
debugging. After system has booted up, it can be set
via /sys/module/acpi/parameters/debug_level.
CONFIG_ACPI_DEBUG must be enabled for this to produce any output.
Available bits (add the numbers together) to enable different
debug output levels of the ACPI subsystem:
0x01 error 0x02 warn 0x04 init 0x08 debug object
0x10 info 0x20 init names 0x40 parse 0x80 load
0x100 dispatch 0x200 execute 0x400 names 0x800 operation region
0x1000 bfield 0x2000 tables 0x4000 values 0x8000 objects
0x10000 resources 0x20000 user requests 0x40000 package.
The number can be in decimal or prefixed with 0x in hex.
Warning: Many of these options can produce a lot of
output and make your system unusable. Be very careful.
which corresponds to the level in an ACPI_DEBUG_PRINT
statement. After system has booted up, this mask
can be set via /sys/module/acpi/parameters/debug_level.
CONFIG_ACPI_DEBUG must be enabled for this to produce
any output. The number can be in decimal or prefixed
with 0x in hex. Some of these options produce so much
output that the system is unusable.
The following global components are defined by the
ACPI CA:
0x01 error
0x02 warn
0x04 init
0x08 debug object
0x10 info
0x20 init names
0x40 parse
0x80 load
0x100 dispatch
0x200 execute
0x400 names
0x800 operation region
0x1000 bfield
0x2000 tables
0x4000 values
0x8000 objects
0x10000 resources
0x20000 user requests
0x40000 package
The number can be in decimal or prefixed with 0x in hex.
Warning: Many of these options can produce a lot of
output and make your system unusable. Be very careful.
acpi.power_nocheck= [HW,ACPI]
Format: 1/0 enable/disable the check of power state.
On some bogus BIOS the _PSC object/_STA object of
power resource can't return the correct device power
state. In such case it is unneccessary to check its
power state again in power transition.
1 : disable the power state check
acpi_pm_good [X86-32,X86-64]
Override the pmtimer bug detection: force the kernel
@ -1711,6 +1738,10 @@ and is between 256 and 4096 characters. It is defined in the file
Override pmtimer IOPort with a hex value.
e.g. pmtmr=0x508
pnp.debug [PNP]
Enable PNP debug messages. This depends on the
CONFIG_PNP_DEBUG_MESSAGES option.
pnpacpi= [ACPI]
{ off }
@ -2208,7 +2239,7 @@ and is between 256 and 4096 characters. It is defined in the file
thermal.crt= [HW,ACPI]
-1: disable all critical trip points in all thermal zones
<degrees C>: lower all critical trip points
<degrees C>: override all critical trip points
thermal.nocrt= [HW,ACPI]
Set to disable actions on ACPI thermal zone

View file

@ -1,7 +1,7 @@
Acer Laptop WMI Extras Driver
http://code.google.com/p/aceracpi
Version 0.1
9th February 2008
Version 0.2
18th August 2008
Copyright 2007-2008 Carlos Corbacho <carlos@strangeworlds.co.uk>
@ -87,17 +87,7 @@ acer-wmi come with built-in wireless. However, should you feel so inclined to
ever wish to remove the card, or swap it out at some point, please get in touch
with me, as we may well be able to gain some data on wireless card detection.
To read the status of the wireless radio (0=off, 1=on):
cat /sys/devices/platform/acer-wmi/wireless
To enable the wireless radio:
echo 1 > /sys/devices/platform/acer-wmi/wireless
To disable the wireless radio:
echo 0 > /sys/devices/platform/acer-wmi/wireless
To set the state of the wireless radio when loading acer-wmi, pass:
wireless=X (where X is 0 or 1)
The wireless radio is exposed through rfkill.
Bluetooth
*********
@ -117,17 +107,7 @@ For the adventurously minded - if you want to buy an internal bluetooth
module off the internet that is compatible with your laptop and fit it, then
it will work just fine with acer-wmi.
To read the status of the bluetooth module (0=off, 1=on):
cat /sys/devices/platform/acer-wmi/wireless
To enable the bluetooth module:
echo 1 > /sys/devices/platform/acer-wmi/bluetooth
To disable the bluetooth module:
echo 0 > /sys/devices/platform/acer-wmi/bluetooth
To set the state of the bluetooth module when loading acer-wmi, pass:
bluetooth=X (where X is 0 or 1)
Bluetooth is exposed through rfkill.
3G
**

View file

@ -1917,6 +1917,8 @@ platforms are moved over to use the flattened-device-tree model.
inverse clock polarity (CPOL) mode
- spi-cpha - (optional) Empty property indicating device requires
shifted clock phase (CPHA) mode
- spi-cs-high - (optional) Empty property indicating device requires
chip select active high
SPI example for an MPC5200 SPI bus:
spi@f00 {

View file

@ -2,13 +2,13 @@
Required properties:
- device_type : Should be "board-control"
- compatible : Should be "fsl,<board>-bcsr"
- reg : Offset and length of the register set for the device
Example:
bcsr@f8000000 {
device_type = "board-control";
compatible = "fsl,mpc8360mds-bcsr";
reg = <f8000000 8000>;
};

View file

@ -0,0 +1,448 @@
Linux UWB + Wireless USB + WiNET
(C) 2005-2006 Intel Corporation
Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.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.
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.
Please visit http://bughost.org/thewiki/Design-overview.txt-1.8 for
updated content.
* Design-overview.txt-1.8
This code implements a Ultra Wide Band stack for Linux, as well as
drivers for the the USB based UWB radio controllers defined in the
Wireless USB 1.0 specification (including Wireless USB host controller
and an Intel WiNET controller).
1. Introduction
1. HWA: Host Wire adapters, your Wireless USB dongle
2. DWA: Device Wired Adaptor, a Wireless USB hub for wired
devices
3. WHCI: Wireless Host Controller Interface, the PCI WUSB host
adapter
2. The UWB stack
1. Devices and hosts: the basic structure
2. Host Controller life cycle
3. On the air: beacons and enumerating the radio neighborhood
4. Device lists
5. Bandwidth allocation
3. Wireless USB Host Controller drivers
4. Glossary
Introduction
UWB is a wide-band communication protocol that is to serve also as the
low-level protocol for others (much like TCP sits on IP). Currently
these others are Wireless USB and TCP/IP, but seems Bluetooth and
Firewire/1394 are coming along.
UWB uses a band from roughly 3 to 10 GHz, transmitting at a max of
~-41dB (or 0.074 uW/MHz--geography specific data is still being
negotiated w/ regulators, so watch for changes). That band is divided in
a bunch of ~1.5 GHz wide channels (or band groups) composed of three
subbands/subchannels (528 MHz each). Each channel is independent of each
other, so you could consider them different "busses". Initially this
driver considers them all a single one.
Radio time is divided in 65536 us long /superframes/, each one divided
in 256 256us long /MASs/ (Media Allocation Slots), which are the basic
time/media allocation units for transferring data. At the beginning of
each superframe there is a Beacon Period (BP), where every device
transmit its beacon on a single MAS. The length of the BP depends on how
many devices are present and the length of their beacons.
Devices have a MAC (fixed, 48 bit address) and a device (changeable, 16
bit address) and send periodic beacons to advertise themselves and pass
info on what they are and do. They advertise their capabilities and a
bunch of other stuff.
The different logical parts of this driver are:
*
*UWB*: the Ultra-Wide-Band stack -- manages the radio and
associated spectrum to allow for devices sharing it. Allows to
control bandwidth assingment, beaconing, scanning, etc
*
*WUSB*: the layer that sits on top of UWB to provide Wireless USB.
The Wireless USB spec defines means to control a UWB radio and to
do the actual WUSB.
HWA: Host Wire adapters, your Wireless USB dongle
WUSB also defines a device called a Host Wire Adaptor (HWA), which in
mere terms is a USB dongle that enables your PC to have UWB and Wireless
USB. The Wireless USB Host Controller in a HWA looks to the host like a
[Wireless] USB controller connected via USB (!)
The HWA itself is broken in two or three main interfaces:
*
*RC*: Radio control -- this implements an interface to the
Ultra-Wide-Band radio controller. The driver for this implements a
USB-based UWB Radio Controller to the UWB stack.
*
*HC*: the wireless USB host controller. It looks like a USB host
whose root port is the radio and the WUSB devices connect to it.
To the system it looks like a separate USB host. The driver (will)
implement a USB host controller (similar to UHCI, OHCI or EHCI)
for which the root hub is the radio...To reiterate: it is a USB
controller that is connected via USB instead of PCI.
*
*WINET*: some HW provide a WiNET interface (IP over UWB). This
package provides a driver for it (it looks like a network
interface, winetX). The driver detects when there is a link up for
their type and kick into gear.
DWA: Device Wired Adaptor, a Wireless USB hub for wired devices
These are the complement to HWAs. They are a USB host for connecting
wired devices, but it is connected to your PC connected via Wireless
USB. To the system it looks like yet another USB host. To the untrained
eye, it looks like a hub that connects upstream wirelessly.
We still offer no support for this; however, it should share a lot of
code with the HWA-RC driver; there is a bunch of factorization work that
has been done to support that in upcoming releases.
WHCI: Wireless Host Controller Interface, the PCI WUSB host adapter
This is your usual PCI device that implements WHCI. Similar in concept
to EHCI, it allows your wireless USB devices (including DWAs) to connect
to your host via a PCI interface. As in the case of the HWA, it has a
Radio Control interface and the WUSB Host Controller interface per se.
There is still no driver support for this, but will be in upcoming
releases.
The UWB stack
The main mission of the UWB stack is to keep a tally of which devices
are in radio proximity to allow drivers to connect to them. As well, it
provides an API for controlling the local radio controllers (RCs from
now on), such as to start/stop beaconing, scan, allocate bandwidth, etc.
Devices and hosts: the basic structure
The main building block here is the UWB device (struct uwb_dev). For
each device that pops up in radio presence (ie: the UWB host receives a
beacon from it) you get a struct uwb_dev that will show up in
/sys/class/uwb and in /sys/bus/uwb/devices.
For each RC that is detected, a new struct uwb_rc is created. In turn, a
RC is also a device, so they also show in /sys/class/uwb and
/sys/bus/uwb/devices, but at the same time, only radio controllers show
up in /sys/class/uwb_rc.
*
[*] The reason for RCs being also devices is that not only we can
see them while enumerating the system device tree, but also on the
radio (their beacons and stuff), so the handling has to be
likewise to that of a device.
Each RC driver is implemented by a separate driver that plugs into the
interface that the UWB stack provides through a struct uwb_rc_ops. The
spec creators have been nice enough to make the message format the same
for HWA and WHCI RCs, so the driver is really a very thin transport that
moves the requests from the UWB API to the device [/uwb_rc_ops->cmd()/]
and sends the replies and notifications back to the API
[/uwb_rc_neh_grok()/]. Notifications are handled to the UWB daemon, that
is chartered, among other things, to keep the tab of how the UWB radio
neighborhood looks, creating and destroying devices as they show up or
dissapear.
Command execution is very simple: a command block is sent and a event
block or reply is expected back. For sending/receiving command/events, a
handle called /neh/ (Notification/Event Handle) is opened with
/uwb_rc_neh_open()/.
The HWA-RC (USB dongle) driver (drivers/uwb/hwa-rc.c) does this job for
the USB connected HWA. Eventually, drivers/whci-rc.c will do the same
for the PCI connected WHCI controller.
Host Controller life cycle
So let's say we connect a dongle to the system: it is detected and
firmware uploaded if needed [for Intel's i1480
/drivers/uwb/ptc/usb.c:ptc_usb_probe()/] and then it is reenumerated.
Now we have a real HWA device connected and
/drivers/uwb/hwa-rc.c:hwarc_probe()/ picks it up, that will set up the
Wire-Adaptor environment and then suck it into the UWB stack's vision of
the world [/drivers/uwb/lc-rc.c:uwb_rc_add()/].
*
[*] The stack should put a new RC to scan for devices
[/uwb_rc_scan()/] so it finds what's available around and tries to
connect to them, but this is policy stuff and should be driven
from user space. As of now, the operator is expected to do it
manually; see the release notes for documentation on the procedure.
When a dongle is disconnected, /drivers/uwb/hwa-rc.c:hwarc_disconnect()/
takes time of tearing everything down safely (or not...).
On the air: beacons and enumerating the radio neighborhood
So assuming we have devices and we have agreed for a channel to connect
on (let's say 9), we put the new RC to beacon:
*
$ echo 9 0 > /sys/class/uwb_rc/uwb0/beacon
Now it is visible. If there were other devices in the same radio channel
and beacon group (that's what the zero is for), the dongle's radio
control interface will send beacon notifications on its
notification/event endpoint (NEEP). The beacon notifications are part of
the event stream that is funneled into the API with
/drivers/uwb/neh.c:uwb_rc_neh_grok()/ and delivered to the UWBD, the UWB
daemon through a notification list.
UWBD wakes up and scans the event list; finds a beacon and adds it to
the BEACON CACHE (/uwb_beca/). If he receives a number of beacons from
the same device, he considers it to be 'onair' and creates a new device
[/drivers/uwb/lc-dev.c:uwbd_dev_onair()/]. Similarly, when no beacons
are received in some time, the device is considered gone and wiped out
[uwbd calls periodically /uwb/beacon.c:uwb_beca_purge()/ that will purge
the beacon cache of dead devices].
Device lists
All UWB devices are kept in the list of the struct bus_type uwb_bus.
Bandwidth allocation
The UWB stack maintains a local copy of DRP availability through
processing of incoming *DRP Availability Change* notifications. This
local copy is currently used to present the current bandwidth
availability to the user through the sysfs file
/sys/class/uwb_rc/uwbx/bw_avail. In the future the bandwidth
availability information will be used by the bandwidth reservation
routines.
The bandwidth reservation routines are in progress and are thus not
present in the current release. When completed they will enable a user
to initiate DRP reservation requests through interaction with sysfs. DRP
reservation requests from remote UWB devices will also be handled. The
bandwidth management done by the UWB stack will include callbacks to the
higher layers will enable the higher layers to use the reservations upon
completion. [Note: The bandwidth reservation work is in progress and
subject to change.]
Wireless USB Host Controller drivers
*WARNING* This section needs a lot of work!
As explained above, there are three different types of HCs in the WUSB
world: HWA-HC, DWA-HC and WHCI-HC.
HWA-HC and DWA-HC share that they are Wire-Adapters (USB or WUSB
connected controllers), and their transfer management system is almost
identical. So is their notification delivery system.
HWA-HC and WHCI-HC share that they are both WUSB host controllers, so
they have to deal with WUSB device life cycle and maintenance, wireless
root-hub
HWA exposes a Host Controller interface (HWA-HC 0xe0/02/02). This has
three endpoints (Notifications, Data Transfer In and Data Transfer
Out--known as NEP, DTI and DTO in the code).
We reserve UWB bandwidth for our Wireless USB Cluster, create a Cluster
ID and tell the HC to use all that. Then we start it. This means the HC
starts sending MMCs.
*
The MMCs are blocks of data defined somewhere in the WUSB1.0 spec
that define a stream in the UWB channel time allocated for sending
WUSB IEs (host to device commands/notifications) and Device
Notifications (device initiated to host). Each host defines a
unique Wireless USB cluster through MMCs. Devices can connect to a
single cluster at the time. The IEs are Information Elements, and
among them are the bandwidth allocations that tell each device
when can they transmit or receive.
Now it all depends on external stimuli.
*New device connection*
A new device pops up, it scans the radio looking for MMCs that give out
the existence of Wireless USB channels. Once one (or more) are found,
selects which one to connect to. Sends a /DN_Connect/ (device
notification connect) during the DNTS (Device Notification Time
Slot--announced in the MMCs
HC picks the /DN_Connect/ out (nep module sends to notif.c for delivery
into /devconnect/). This process starts the authentication process for
the device. First we allocate a /fake port/ and assign an
unauthenticated address (128 to 255--what we really do is
0x80 | fake_port_idx). We fiddle with the fake port status and /khubd/
sees a new connection, so he moves on to enable the fake port with a reset.
So now we are in the reset path -- we know we have a non-yet enumerated
device with an unauthorized address; we ask user space to authenticate
(FIXME: not yet done, similar to bluetooth pairing), then we do the key
exchange (FIXME: not yet done) and issue a /set address 0/ to bring the
device to the default state. Device is authenticated.
From here, the USB stack takes control through the usb_hcd ops. khubd
has seen the port status changes, as we have been toggling them. It will
start enumerating and doing transfers through usb_hcd->urb_enqueue() to
read descriptors and move our data.
*Device life cycle and keep alives*
Everytime there is a succesful transfer to/from a device, we update a
per-device activity timestamp. If not, every now and then we check and
if the activity timestamp gets old, we ping the device by sending it a
Keep Alive IE; it responds with a /DN_Alive/ pong during the DNTS (this
arrives to us as a notification through
devconnect.c:wusb_handle_dn_alive(). If a device times out, we
disconnect it from the system (cleaning up internal information and
toggling the bits in the fake hub port, which kicks khubd into removing
the rest of the stuff).
This is done through devconnect:__wusb_check_devs(), which will scan the
device list looking for whom needs refreshing.
If the device wants to disconnect, it will either die (ugly) or send a
/DN_Disconnect/ that will prompt a disconnection from the system.
*Sending and receiving data*
Data is sent and received through /Remote Pipes/ (rpipes). An rpipe is
/aimed/ at an endpoint in a WUSB device. This is the same for HWAs and
DWAs.
Each HC has a number of rpipes and buffers that can be assigned to them;
when doing a data transfer (xfer), first the rpipe has to be aimed and
prepared (buffers assigned), then we can start queueing requests for
data in or out.
Data buffers have to be segmented out before sending--so we send first a
header (segment request) and then if there is any data, a data buffer
immediately after to the DTI interface (yep, even the request). If our
buffer is bigger than the max segment size, then we just do multiple
requests.
[This sucks, because doing USB scatter gatter in Linux is resource
intensive, if any...not that the current approach is not. It just has to
be cleaned up a lot :)].
If reading, we don't send data buffers, just the segment headers saying
we want to read segments.
When the xfer is executed, we receive a notification that says data is
ready in the DTI endpoint (handled through
xfer.c:wa_handle_notif_xfer()). In there we read from the DTI endpoint a
descriptor that gives us the status of the transfer, its identification
(given when we issued it) and the segment number. If it was a data read,
we issue another URB to read into the destination buffer the chunk of
data coming out of the remote endpoint. Done, wait for the next guy. The
callbacks for the URBs issued from here are the ones that will declare
the xfer complete at some point and call it's callback.
Seems simple, but the implementation is not trivial.
*
*WARNING* Old!!
The main xfer descriptor, wa_xfer (equivalent to a URB) contains an
array of segments, tallys on segments and buffers and callback
information. Buried in there is a lot of URBs for executing the segments
and buffer transfers.
For OUT xfers, there is an array of segments, one URB for each, another
one of buffer URB. When submitting, we submit URBs for segment request
1, buffer 1, segment 2, buffer 2...etc. Then we wait on the DTI for xfer
result data; when all the segments are complete, we call the callback to
finalize the transfer.
For IN xfers, we only issue URBs for the segments we want to read and
then wait for the xfer result data.
*URB mapping into xfers*
This is done by hwahc_op_urb_[en|de]queue(). In enqueue() we aim an
rpipe to the endpoint where we have to transmit, create a transfer
context (wa_xfer) and submit it. When the xfer is done, our callback is
called and we assign the status bits and release the xfer resources.
In dequeue() we are basically cancelling/aborting the transfer. We issue
a xfer abort request to the HC, cancell all the URBs we had submitted
and not yet done and when all that is done, the xfer callback will be
called--this will call the URB callback.
Glossary
*DWA* -- Device Wire Adapter
USB host, wired for downstream devices, upstream connects wirelessly
with Wireless USB.
*EVENT* -- Response to a command on the NEEP
*HWA* -- Host Wire Adapter / USB dongle for UWB and Wireless USB
*NEH* -- Notification/Event Handle
Handle/file descriptor for receiving notifications or events. The WA
code requires you to get one of this to listen for notifications or
events on the NEEP.
*NEEP* -- Notification/Event EndPoint
Stuff related to the management of the first endpoint of a HWA USB
dongle that is used to deliver an stream of events and notifications to
the host.
*NOTIFICATION* -- Message coming in the NEEP as response to something.
*RC* -- Radio Control
Design-overview.txt-1.8 (last edited 2006-11-04 12:22:24 by
InakyPerezGonzalez)

139
Documentation/usb/wusb-cbaf Normal file
View file

@ -0,0 +1,139 @@
#! /bin/bash
#
set -e
progname=$(basename $0)
function help
{
cat <<EOF
Usage: $progname COMMAND DEVICEs [ARGS]
Command for manipulating the pairing/authentication credentials of a
Wireless USB device that supports wired-mode Cable-Based-Association.
Works in conjunction with the wusb-cba.ko driver from http://linuxuwb.org.
DEVICE
sysfs path to the device to authenticate; for example, both this
guys are the same:
/sys/devices/pci0000:00/0000:00:1d.7/usb1/1-4/1-4.4/1-4.4:1.1
/sys/bus/usb/drivers/wusb-cbaf/1-4.4:1.1
COMMAND/ARGS are
start
Start a WUSB host controller (by setting up a CHID)
set-chid DEVICE HOST-CHID HOST-BANDGROUP HOST-NAME
Sets host information in the device; after this you can call the
get-cdid to see how does this device report itself to us.
get-cdid DEVICE
Get the device ID associated to the HOST-CHDI we sent with
'set-chid'. We might not know about it.
set-cc DEVICE
If we allow the device to connect, set a random new CDID and CK
(connection key). Device saves them for the next time it wants to
connect wireless. We save them for that next time also so we can
authenticate the device (when we see the CDID he uses to id
itself) and the CK to crypto talk to it.
CHID is always 16 hex bytes in 'XX YY ZZ...' form
BANDGROUP is almost always 0001
Examples:
You can default most arguments to '' to get a sane value:
$ $progname set-chid '' '' '' "My host name"
A full sequence:
$ $progname set-chid '' '' '' "My host name"
$ $progname get-cdid ''
$ $progname set-cc ''
EOF
}
# Defaults
# FIXME: CHID should come from a database :), band group from the host
host_CHID="00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff"
host_band_group="0001"
host_name=$(hostname)
devs="$(echo /sys/bus/usb/drivers/wusb-cbaf/[0-9]*)"
hdevs="$(for h in /sys/class/uwb_rc/*/wusbhc; do readlink -f $h; done)"
result=0
case $1 in
start)
for dev in ${2:-$hdevs}
do
uwb_rc=$(readlink -f $dev/uwb_rc)
if cat $uwb_rc/beacon | grep -q -- "-1"
then
echo 13 0 > $uwb_rc/beacon
echo I: started beaconing on ch 13 on $(basename $uwb_rc) >&2
fi
echo $host_CHID > $dev/wusb_chid
echo I: started host $(basename $dev) >&2
done
;;
stop)
for dev in ${2:-$hdevs}
do
echo 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > $dev/wusb_chid
echo I: stopped host $(basename $dev) >&2
uwb_rc=$(readlink -f $dev/uwb_rc)
echo -1 | cat > $uwb_rc/beacon
echo I: stopped beaconing on $(basename $uwb_rc) >&2
done
;;
set-chid)
shift
for dev in ${2:-$devs}; do
echo "${4:-$host_name}" > $dev/wusb_host_name
echo "${3:-$host_band_group}" > $dev/wusb_host_band_groups
echo ${2:-$host_CHID} > $dev/wusb_chid
done
;;
get-cdid)
for dev in ${2:-$devs}
do
cat $dev/wusb_cdid
done
;;
set-cc)
for dev in ${2:-$devs}; do
shift
CDID="$(head --bytes=16 /dev/urandom | od -tx1 -An)"
CK="$(head --bytes=16 /dev/urandom | od -tx1 -An)"
echo "$CDID" > $dev/wusb_cdid
echo "$CK" > $dev/wusb_ck
echo I: CC set >&2
echo "CHID: $(cat $dev/wusb_chid)"
echo "CDID:$CDID"
echo "CK: $CK"
done
;;
help|h|--help|-h)
help
;;
*)
echo "E: Unknown usage" 1>&2
help 1>&2
result=1
esac
exit $result

View file

@ -378,8 +378,9 @@ T: git://git.kernel.org/pub/scm/linux/kernel/git/joro/linux-2.6-iommu.git
S: Supported
AMD MICROCODE UPDATE SUPPORT
P: Peter Oruba
M: peter.oruba@amd.com
P: Andreas Herrmann
M: andeas.herrmann3@amd.com
L: amd64-microcode@amd64.org
S: Supported
AMS (Apple Motion Sensor) DRIVER
@ -1053,6 +1054,12 @@ L: cbe-oss-dev@ozlabs.org
W: http://www.ibm.com/developerworks/power/cell/
S: Supported
CERTIFIED WIRELESS USB (WUSB) SUBSYSTEM:
P: David Vrabel
M: david.vrabel@csr.com
L: linux-usb@vger.kernel.org
S: Supported
CFAG12864B LCD DRIVER
P: Miguel Ojeda Sandonis
M: miguel.ojeda.sandonis@gmail.com
@ -1427,8 +1434,8 @@ M: rdunlap@xenotime.net
S: Maintained
DOCKING STATION DRIVER
P: Kristen Carlson Accardi
M: kristen.c.accardi@intel.com
P: Shaohua Li
M: shaohua.li@intel.com
L: linux-acpi@vger.kernel.org
S: Supported
@ -2103,6 +2110,12 @@ L: linux-ide@vger.kernel.org
L: linux-scsi@vger.kernel.org
S: Orphan
IDLE-I7300
P: Andy Henroid
M: andrew.d.henroid@intel.com
L: linux-pm@lists.linux-foundation.org
S: Supported
IEEE 1394 SUBSYSTEM (drivers/ieee1394)
P: Ben Collins
M: ben.collins@ubuntu.com
@ -2176,6 +2189,13 @@ M: maciej.sosnowski@intel.com
L: linux-kernel@vger.kernel.org
S: Supported
INTEL IOMMU (VT-d)
P: David Woodhouse
M: dwmw2@infradead.org
L: iommu@lists.linux-foundation.org
T: git://git.infradead.org/iommu-2.6.git
S: Supported
INTEL IOP-ADMA DMA DRIVER
P: Dan Williams
M: dan.j.williams@intel.com
@ -2928,9 +2948,9 @@ S: Maintained
NETEFFECT IWARP RNIC DRIVER (IW_NES)
P: Faisal Latif
M: flatif@neteffect.com
M: faisal.latif@intel.com
P: Chien Tung
M: ctung@neteffect.com
M: chien.tin.tung@intel.com
L: general@lists.openfabrics.org
W: http://www.neteffect.com
S: Supported
@ -3173,6 +3193,11 @@ M: olof@lixom.net
L: i2c@lm-sensors.org
S: Maintained
PANASONIC LAPTOP ACPI EXTRAS DRIVER
P: Harald Welte
M: laforge@gnumonks.org
S: Maintained
PANASONIC MN10300/AM33 PORT
P: David Howells
M: dhowells@redhat.com
@ -3244,11 +3269,6 @@ L: linux-pci@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/jbarnes/pci-2.6.git
S: Supported
PCI HOTPLUG CORE
P: Kristen Carlson Accardi
M: kristen.c.accardi@intel.com
S: Supported
PCIE HOTPLUG DRIVER
P: Kristen Carlson Accardi
M: kristen.c.accardi@intel.com
@ -4191,6 +4211,12 @@ L: sparclinux@vger.kernel.org
T: git kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6.git
S: Maintained
ULTRA-WIDEBAND (UWB) SUBSYSTEM:
P: David Vrabel
M: david.vrabel@csr.com
L: linux-usb@vger.kernel.org
S: Supported
UNIFORM CDROM DRIVER
P: Jens Axboe
M: axboe@kernel.dk
@ -4616,6 +4642,11 @@ M: zaga@fly.cc.fer.hr
L: linux-scsi@vger.kernel.org
S: Maintained
WIMEDIA LLC PROTOCOL (WLP) SUBSYSTEM
P: David Vrabel
M: david.vrabel@csr.com
S: Maintained
WISTRON LAPTOP BUTTON DRIVER
P: Miloslav Trmac
M: mitr@volny.cz

View file

@ -1,8 +1,8 @@
VERSION = 2
PATCHLEVEL = 6
SUBLEVEL = 27
EXTRAVERSION =
NAME = Rotary Wombat
SUBLEVEL = 28
EXTRAVERSION = -rc2
NAME = Killer Bat of Doom
# *DOCUMENTATION*
# To see a list of typical targets execute "make help"
@ -437,7 +437,7 @@ ifeq ($(config-targets),1)
# KBUILD_DEFCONFIG may point out an alternative default configuration
# used for 'make defconfig'
include $(srctree)/arch/$(SRCARCH)/Makefile
export KBUILD_DEFCONFIG
export KBUILD_DEFCONFIG KBUILD_KCONFIG
config %config: scripts_basic outputmakefile FORCE
$(Q)mkdir -p include/linux include/config

View file

@ -165,14 +165,11 @@ osf_getdirentries(unsigned int fd, struct osf_dirent __user *dirent,
buf.error = 0;
error = vfs_readdir(file, osf_filldir, &buf);
if (error < 0)
goto out_putf;
error = buf.error;
if (error >= 0)
error = buf.error;
if (count != buf.count)
error = count - buf.count;
out_putf:
fput(file);
out:
return error;
@ -986,10 +983,12 @@ asmlinkage int
osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
struct timeval32 __user *tvp)
{
s64 timeout = MAX_SCHEDULE_TIMEOUT;
struct timespec end_time, *to = NULL;
if (tvp) {
time_t sec, usec;
to = &end_time;
if (!access_ok(VERIFY_READ, tvp, sizeof(*tvp))
|| __get_user(sec, &tvp->tv_sec)
|| __get_user(usec, &tvp->tv_usec)) {
@ -999,14 +998,13 @@ osf_select(int n, fd_set __user *inp, fd_set __user *outp, fd_set __user *exp,
if (sec < 0 || usec < 0)
return -EINVAL;
if ((unsigned long) sec < MAX_SELECT_SECONDS) {
timeout = (usec + 1000000/HZ - 1) / (1000000/HZ);
timeout += sec * (unsigned long) HZ;
}
if (poll_select_set_timeout(to, sec, usec * NSEC_PER_USEC))
return -EINVAL;
}
/* OSF does not copy back the remaining time. */
return core_sys_select(n, inp, outp, exp, &timeout);
return core_sys_select(n, inp, outp, exp, to);
}
struct rusage32 {

View file

@ -106,7 +106,7 @@ op_axp_stop(void)
}
static int
op_axp_create_files(struct super_block * sb, struct dentry * root)
op_axp_create_files(struct super_block *sb, struct dentry *root)
{
int i;

View file

@ -355,7 +355,7 @@ config ARCH_IXP4XX
select GENERIC_GPIO
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
select ZONE_DMA if PCI
select DMABOUNCE if PCI
help
Support for Intel's IXP4XX (XScale) family of processors.
@ -539,16 +539,15 @@ config ARCH_OMAP
help
Support for TI's OMAP platform (OMAP1 and OMAP2).
config ARCH_MSM7X00A
bool "Qualcomm MSM7X00A"
config ARCH_MSM
bool "Qualcomm MSM"
select GENERIC_TIME
select GENERIC_CLOCKEVENTS
help
Support for Qualcomm MSM7X00A based systems. This runs on the ARM11
apps processor of the MSM7X00A and depends on a shared memory
Support for Qualcomm MSM7K based systems. This runs on the ARM11
apps processor of the MSM7K and depends on a shared memory
interface to the ARM9 modem processor which runs the baseband stack
and controls some vital subsystems (clock and power control, etc).
<http://www.cdmatech.com/products/msm7200_chipset_solution.jsp>
endchoice
@ -1255,6 +1254,8 @@ source "drivers/hid/Kconfig"
source "drivers/usb/Kconfig"
source "drivers/uwb/Kconfig"
source "drivers/mmc/Kconfig"
source "drivers/memstick/Kconfig"

View file

@ -141,7 +141,7 @@ endif
machine-$(CONFIG_ARCH_MX3) := mx3
machine-$(CONFIG_ARCH_ORION5X) := orion5x
plat-$(CONFIG_PLAT_ORION) := orion
machine-$(CONFIG_ARCH_MSM7X00A) := msm
machine-$(CONFIG_ARCH_MSM) := msm
machine-$(CONFIG_ARCH_LOKI) := loki
machine-$(CONFIG_ARCH_MV78XX0) := mv78xx0

View file

@ -13,10 +13,10 @@ config ICST307
config SA1111
bool
select DMABOUNCE if !ARCH_PXA
select ZONE_DMA if !ARCH_PXA
config DMABOUNCE
bool
select ZONE_DMA
config TIMER_ACORN
bool

View file

@ -581,6 +581,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
goto out;
}
#ifdef CONFIG_DMABOUNCE
/*
* If the parent device has a DMA mask associated with it,
* propagate it down to the children.
@ -598,6 +599,7 @@ sa1111_init_one_child(struct sa1111 *sachip, struct resource *parent,
}
}
}
#endif
out:
return ret;
@ -937,7 +939,7 @@ static int sa1111_resume(struct platform_device *dev)
#define sa1111_resume NULL
#endif
static int sa1111_probe(struct platform_device *pdev)
static int __devinit sa1111_probe(struct platform_device *pdev)
{
struct resource *mem;
int irq;

File diff suppressed because it is too large Load diff

View file

@ -133,7 +133,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
# CONFIG_ARCH_LH7A40X is not set
# CONFIG_ARCH_DAVINCI is not set
# CONFIG_ARCH_OMAP is not set
CONFIG_ARCH_MSM7X00A=y
CONFIG_ARCH_MSM=y
#
# Boot options

File diff suppressed because it is too large Load diff

View file

@ -147,6 +147,7 @@ CONFIG_ARCH_PXA=y
# CONFIG_MACH_MAINSTONE is not set
# CONFIG_ARCH_PXA_IDP is not set
# CONFIG_PXA_SHARPSL is not set
CONFIG_TRIZEPS_PXA=y
CONFIG_MACH_TRIZEPS4=y
CONFIG_MACH_TRIZEPS4_CONXS=y
# CONFIG_MACH_TRIZEPS4_ANY is not set

View file

@ -165,7 +165,7 @@
__res = __m; \
asm ( "umlal %Q0, %R0, %Q1, %Q2\n\t" \
"mov %Q0, #0" \
: "+r" (__res) \
: "+&r" (__res) \
: "r" (__m), "r" (__n) \
: "cc" ); \
} else { \
@ -182,7 +182,7 @@
"umlal %R0, %Q0, %Q1, %R2\n\t" \
"mov %R0, #0\n\t" \
"umlal %Q0, %R0, %R1, %R2" \
: "+r" (__res) \
: "+&r" (__res) \
: "r" (__m), "r" (__n) \
: "cc" ); \
} else { \
@ -192,7 +192,7 @@
"adds %Q0, %1, %Q0\n\t" \
"adc %R0, %R0, #0\n\t" \
"umlal %Q0, %R0, %R2, %R3" \
: "+r" (__res), "+r" (__z) \
: "+&r" (__res), "+&r" (__z) \
: "r" (__m), "r" (__n) \
: "cc" ); \
} \

View file

@ -404,6 +404,7 @@ static void gpio_irq_handler(unsigned irq, struct irq_desc *desc)
}
pin = bank->chipbase;
gpio = &irq_desc[pin];
while (isr) {
if (isr & 1) {

View file

@ -89,6 +89,8 @@
* node 3: 0xd8000000 - 0xdfffffff
*/
#define NODE_MEM_SIZE_BITS 24
#define SECTION_SIZE_BITS 24
#define MAX_PHYSMEM_BITS 32
#endif

View file

@ -167,11 +167,6 @@ config MACH_GTWX5715
comment "IXP4xx Options"
config DMABOUNCE
bool
default y
depends on PCI
config IXP4XX_INDIRECT_PCI
bool "Use indirect PCI memory access"
depends on PCI

View file

@ -2,4 +2,4 @@ obj-y += common.o addr-map.o irq.o pcie.o
obj-$(CONFIG_MACH_DB88F6281_BP) += db88f6281-bp-setup.o
obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6192-nas-setup.o
obj-$(CONFIG_MACH_RD88F6192_NAS) += rd88f6281-setup.o
obj-$(CONFIG_MACH_RD88F6281) += rd88f6281-setup.o

View file

@ -16,6 +16,7 @@
#include <linux/mv643xx_eth.h>
#include <linux/ata_platform.h>
#include <linux/spi/orion_spi.h>
#include <net/dsa.h>
#include <asm/page.h>
#include <asm/timex.h>
#include <asm/mach/map.h>
@ -151,6 +152,40 @@ void __init kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data)
}
/*****************************************************************************
* Ethernet switch
****************************************************************************/
static struct resource kirkwood_switch_resources[] = {
{
.start = 0,
.end = 0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device kirkwood_switch_device = {
.name = "dsa",
.id = 0,
.num_resources = 0,
.resource = kirkwood_switch_resources,
};
void __init kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq)
{
if (irq != NO_IRQ) {
kirkwood_switch_resources[0].start = irq;
kirkwood_switch_resources[0].end = irq;
kirkwood_switch_device.num_resources = 1;
}
d->mii_bus = &kirkwood_ge00_shared.dev;
d->netdev = &kirkwood_ge00.dev;
kirkwood_switch_device.dev.platform_data = d;
platform_device_register(&kirkwood_switch_device);
}
/*****************************************************************************
* SoC RTC
****************************************************************************/

View file

@ -11,6 +11,7 @@
#ifndef __ARCH_KIRKWOOD_COMMON_H
#define __ARCH_KIRKWOOD_COMMON_H
struct dsa_platform_data;
struct mv643xx_eth_platform_data;
struct mv_sata_platform_data;
@ -29,6 +30,7 @@ void kirkwood_pcie_id(u32 *dev, u32 *rev);
void kirkwood_ehci_init(void);
void kirkwood_ge00_init(struct mv643xx_eth_platform_data *eth_data);
void kirkwood_ge00_switch_init(struct dsa_platform_data *d, int irq);
void kirkwood_pcie_init(void);
void kirkwood_rtc_init(void);
void kirkwood_sata_init(struct mv_sata_platform_data *sata_data);

View file

@ -19,6 +19,7 @@
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/pci.h>
@ -74,6 +75,15 @@ static struct mv643xx_eth_platform_data rd88f6281_ge00_data = {
.duplex = DUPLEX_FULL,
};
static struct dsa_platform_data rd88f6281_switch_data = {
.port_names[0] = "lan1",
.port_names[1] = "lan2",
.port_names[2] = "lan3",
.port_names[3] = "lan4",
.port_names[4] = "wan",
.port_names[5] = "cpu",
};
static struct mv_sata_platform_data rd88f6281_sata_data = {
.n_ports = 2,
};
@ -87,6 +97,7 @@ static void __init rd88f6281_init(void)
kirkwood_ehci_init();
kirkwood_ge00_init(&rd88f6281_ge00_data);
kirkwood_ge00_switch_init(&rd88f6281_switch_data, NO_IRQ);
kirkwood_rtc_init();
kirkwood_sata_init(&rd88f6281_sata_data);
kirkwood_uart0_init();

View file

@ -1,18 +1,13 @@
if ARCH_MSM7X00A
if ARCH_MSM
comment "MSM7X00A Board Type"
depends on ARCH_MSM7X00A
comment "MSM Board Type"
depends on ARCH_MSM
config MACH_HALIBUT
depends on ARCH_MSM7X00A
depends on ARCH_MSM
default y
bool "Halibut Board (QCT SURF7200A)"
bool "Halibut Board (QCT SURF7201A)"
help
Support for the Qualcomm SURF7200A eval board.
config MSM7X00A_IDLE
depends on ARCH_MSM7X00A
default y
bool "Idle Support for MSM7X00A"
Support for the Qualcomm SURF7201A eval board.
endif

View file

@ -1,7 +1,8 @@
obj-y += io.o idle.o irq.o timer.o dma.o
# Common code for board init
obj-y += common.o
obj-y += devices.o
obj-y += proc_comm.o
obj-y += vreg.o
obj-y += clock.o clock-7x01a.o
obj-$(CONFIG_MACH_HALIBUT) += board-halibut.o

View file

@ -33,6 +33,8 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include "devices.h"
static struct resource smc91x_resources[] = {
[0] = {
.start = 0x9C004300,
@ -53,31 +55,12 @@ static struct platform_device smc91x_device = {
.resource = smc91x_resources,
};
static void mddi0_panel_power(int on)
{
}
static struct msm_mddi_platform_data msm_mddi0_pdata = {
.panel_power = mddi0_panel_power,
.has_vsync_irq = 0,
};
static struct platform_device msm_mddi0_device = {
.name = "msm_mddi",
.id = 0,
.dev = {
.platform_data = &msm_mddi0_pdata
},
};
static struct platform_device msm_serial0_device = {
.name = "msm_serial",
.id = 0,
};
static struct platform_device *devices[] __initdata = {
&msm_serial0_device,
&msm_mddi0_device,
&msm_device_uart3,
&msm_device_smd,
&msm_device_nand,
&msm_device_hsusb,
&msm_device_i2c,
&smc91x_device,
};
@ -91,20 +74,15 @@ static void __init halibut_init_irq(void)
static void __init halibut_init(void)
{
platform_add_devices(devices, ARRAY_SIZE(devices));
msm_add_devices();
}
static void __init halibut_map_io(void)
{
msm_map_common_io();
msm_clock_init();
}
MACHINE_START(HALIBUT, "Halibut Board (QCT SURF7200A)")
/* UART for LL DEBUG */
.phys_io = MSM_UART1_PHYS,
.io_pg_offst = ((MSM_UART1_BASE) >> 18) & 0xfffc,
.boot_params = 0x10000100,
.map_io = halibut_map_io,
.init_irq = halibut_init_irq,

View file

@ -0,0 +1,126 @@
/* arch/arm/mach-msm/clock-7x01a.c
*
* Clock tables for MSM7X01A
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007 QUALCOMM Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include "clock.h"
#include "devices.h"
/* clock IDs used by the modem processor */
#define ACPU_CLK 0 /* Applications processor clock */
#define ADM_CLK 1 /* Applications data mover clock */
#define ADSP_CLK 2 /* ADSP clock */
#define EBI1_CLK 3 /* External bus interface 1 clock */
#define EBI2_CLK 4 /* External bus interface 2 clock */
#define ECODEC_CLK 5 /* External CODEC clock */
#define EMDH_CLK 6 /* External MDDI host clock */
#define GP_CLK 7 /* General purpose clock */
#define GRP_CLK 8 /* Graphics clock */
#define I2C_CLK 9 /* I2C clock */
#define ICODEC_RX_CLK 10 /* Internal CODEX RX clock */
#define ICODEC_TX_CLK 11 /* Internal CODEX TX clock */
#define IMEM_CLK 12 /* Internal graphics memory clock */
#define MDC_CLK 13 /* MDDI client clock */
#define MDP_CLK 14 /* Mobile display processor clock */
#define PBUS_CLK 15 /* Peripheral bus clock */
#define PCM_CLK 16 /* PCM clock */
#define PMDH_CLK 17 /* Primary MDDI host clock */
#define SDAC_CLK 18 /* Stereo DAC clock */
#define SDC1_CLK 19 /* Secure Digital Card clocks */
#define SDC1_PCLK 20
#define SDC2_CLK 21
#define SDC2_PCLK 22
#define SDC3_CLK 23
#define SDC3_PCLK 24
#define SDC4_CLK 25
#define SDC4_PCLK 26
#define TSIF_CLK 27 /* Transport Stream Interface clocks */
#define TSIF_REF_CLK 28
#define TV_DAC_CLK 29 /* TV clocks */
#define TV_ENC_CLK 30
#define UART1_CLK 31 /* UART clocks */
#define UART2_CLK 32
#define UART3_CLK 33
#define UART1DM_CLK 34
#define UART2DM_CLK 35
#define USB_HS_CLK 36 /* High speed USB core clock */
#define USB_HS_PCLK 37 /* High speed USB pbus clock */
#define USB_OTG_CLK 38 /* Full speed USB clock */
#define VDC_CLK 39 /* Video controller clock */
#define VFE_CLK 40 /* Camera / Video Front End clock */
#define VFE_MDC_CLK 41 /* VFE MDDI client clock */
#define NR_CLKS 42
#define CLOCK(clk_name, clk_id, clk_dev, clk_flags) { \
.name = clk_name, \
.id = clk_id, \
.flags = clk_flags, \
.dev = clk_dev, \
}
#define OFF CLKFLAG_AUTO_OFF
#define MINMAX CLKFLAG_USE_MIN_MAX_TO_SET
struct clk msm_clocks[] = {
CLOCK("adm_clk", ADM_CLK, NULL, 0),
CLOCK("adsp_clk", ADSP_CLK, NULL, 0),
CLOCK("ebi1_clk", EBI1_CLK, NULL, 0),
CLOCK("ebi2_clk", EBI2_CLK, NULL, 0),
CLOCK("ecodec_clk", ECODEC_CLK, NULL, 0),
CLOCK("emdh_clk", EMDH_CLK, NULL, OFF),
CLOCK("gp_clk", GP_CLK, NULL, 0),
CLOCK("grp_clk", GRP_CLK, NULL, OFF),
CLOCK("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0),
CLOCK("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0),
CLOCK("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0),
CLOCK("imem_clk", IMEM_CLK, NULL, OFF),
CLOCK("mdc_clk", MDC_CLK, NULL, 0),
CLOCK("mdp_clk", MDP_CLK, NULL, OFF),
CLOCK("pbus_clk", PBUS_CLK, NULL, 0),
CLOCK("pcm_clk", PCM_CLK, NULL, 0),
CLOCK("pmdh_clk", PMDH_CLK, NULL, OFF | MINMAX),
CLOCK("sdac_clk", SDAC_CLK, NULL, OFF),
CLOCK("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF),
CLOCK("sdc_pclk", SDC1_PCLK, &msm_device_sdc1.dev, OFF),
CLOCK("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF),
CLOCK("sdc_pclk", SDC2_PCLK, &msm_device_sdc2.dev, OFF),
CLOCK("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF),
CLOCK("sdc_pclk", SDC3_PCLK, &msm_device_sdc3.dev, OFF),
CLOCK("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF),
CLOCK("sdc_pclk", SDC4_PCLK, &msm_device_sdc4.dev, OFF),
CLOCK("tsif_clk", TSIF_CLK, NULL, 0),
CLOCK("tsif_ref_clk", TSIF_REF_CLK, NULL, 0),
CLOCK("tv_dac_clk", TV_DAC_CLK, NULL, 0),
CLOCK("tv_enc_clk", TV_ENC_CLK, NULL, 0),
CLOCK("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF),
CLOCK("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0),
CLOCK("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF),
CLOCK("uart1dm_clk", UART1DM_CLK, NULL, OFF),
CLOCK("uart2dm_clk", UART2DM_CLK, NULL, 0),
CLOCK("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF),
CLOCK("usb_hs_pclk", USB_HS_PCLK, &msm_device_hsusb.dev, OFF),
CLOCK("usb_otg_clk", USB_OTG_CLK, NULL, 0),
CLOCK("vdc_clk", VDC_CLK, NULL, OFF | MINMAX),
CLOCK("vfe_clk", VFE_CLK, NULL, OFF),
CLOCK("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF),
};
unsigned msm_num_clocks = ARRAY_SIZE(msm_clocks);

218
arch/arm/mach-msm/clock.c Normal file
View file

@ -0,0 +1,218 @@
/* arch/arm/mach-msm/clock.c
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007 QUALCOMM Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/list.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/spinlock.h>
#include "clock.h"
#include "proc_comm.h"
static DEFINE_MUTEX(clocks_mutex);
static DEFINE_SPINLOCK(clocks_lock);
static LIST_HEAD(clocks);
/*
* glue for the proc_comm interface
*/
static inline int pc_clk_enable(unsigned id)
{
return msm_proc_comm(PCOM_CLKCTL_RPC_ENABLE, &id, NULL);
}
static inline void pc_clk_disable(unsigned id)
{
msm_proc_comm(PCOM_CLKCTL_RPC_DISABLE, &id, NULL);
}
static inline int pc_clk_set_rate(unsigned id, unsigned rate)
{
return msm_proc_comm(PCOM_CLKCTL_RPC_SET_RATE, &id, &rate);
}
static inline int pc_clk_set_min_rate(unsigned id, unsigned rate)
{
return msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &id, &rate);
}
static inline int pc_clk_set_max_rate(unsigned id, unsigned rate)
{
return msm_proc_comm(PCOM_CLKCTL_RPC_MAX_RATE, &id, &rate);
}
static inline int pc_clk_set_flags(unsigned id, unsigned flags)
{
return msm_proc_comm(PCOM_CLKCTL_RPC_SET_FLAGS, &id, &flags);
}
static inline unsigned pc_clk_get_rate(unsigned id)
{
if (msm_proc_comm(PCOM_CLKCTL_RPC_RATE, &id, NULL))
return 0;
else
return id;
}
static inline unsigned pc_clk_is_enabled(unsigned id)
{
if (msm_proc_comm(PCOM_CLKCTL_RPC_ENABLED, &id, NULL))
return 0;
else
return id;
}
static inline int pc_pll_request(unsigned id, unsigned on)
{
on = !!on;
return msm_proc_comm(PCOM_CLKCTL_RPC_PLL_REQUEST, &id, &on);
}
/*
* Standard clock functions defined in include/linux/clk.h
*/
struct clk *clk_get(struct device *dev, const char *id)
{
struct clk *clk;
mutex_lock(&clocks_mutex);
list_for_each_entry(clk, &clocks, list)
if (!strcmp(id, clk->name) && clk->dev == dev)
goto found_it;
list_for_each_entry(clk, &clocks, list)
if (!strcmp(id, clk->name) && clk->dev == NULL)
goto found_it;
clk = ERR_PTR(-ENOENT);
found_it:
mutex_unlock(&clocks_mutex);
return clk;
}
EXPORT_SYMBOL(clk_get);
void clk_put(struct clk *clk)
{
}
EXPORT_SYMBOL(clk_put);
int clk_enable(struct clk *clk)
{
unsigned long flags;
spin_lock_irqsave(&clocks_lock, flags);
clk->count++;
if (clk->count == 1)
pc_clk_enable(clk->id);
spin_unlock_irqrestore(&clocks_lock, flags);
return 0;
}
EXPORT_SYMBOL(clk_enable);
void clk_disable(struct clk *clk)
{
unsigned long flags;
spin_lock_irqsave(&clocks_lock, flags);
BUG_ON(clk->count == 0);
clk->count--;
if (clk->count == 0)
pc_clk_disable(clk->id);
spin_unlock_irqrestore(&clocks_lock, flags);
}
EXPORT_SYMBOL(clk_disable);
unsigned long clk_get_rate(struct clk *clk)
{
return pc_clk_get_rate(clk->id);
}
EXPORT_SYMBOL(clk_get_rate);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
int ret;
if (clk->flags & CLKFLAG_USE_MIN_MAX_TO_SET) {
ret = pc_clk_set_max_rate(clk->id, rate);
if (ret)
return ret;
return pc_clk_set_min_rate(clk->id, rate);
}
return pc_clk_set_rate(clk->id, rate);
}
EXPORT_SYMBOL(clk_set_rate);
int clk_set_parent(struct clk *clk, struct clk *parent)
{
return -ENOSYS;
}
EXPORT_SYMBOL(clk_set_parent);
struct clk *clk_get_parent(struct clk *clk)
{
return ERR_PTR(-ENOSYS);
}
EXPORT_SYMBOL(clk_get_parent);
int clk_set_flags(struct clk *clk, unsigned long flags)
{
if (clk == NULL || IS_ERR(clk))
return -EINVAL;
return pc_clk_set_flags(clk->id, flags);
}
EXPORT_SYMBOL(clk_set_flags);
void __init msm_clock_init(void)
{
unsigned n;
spin_lock_init(&clocks_lock);
mutex_lock(&clocks_mutex);
for (n = 0; n < msm_num_clocks; n++)
list_add_tail(&msm_clocks[n].list, &clocks);
mutex_unlock(&clocks_mutex);
}
/* The bootloader and/or AMSS may have left various clocks enabled.
* Disable any clocks that belong to us (CLKFLAG_AUTO_OFF) but have
* not been explicitly enabled by a clk_enable() call.
*/
static int __init clock_late_init(void)
{
unsigned long flags;
struct clk *clk;
unsigned count = 0;
mutex_lock(&clocks_mutex);
list_for_each_entry(clk, &clocks, list) {
if (clk->flags & CLKFLAG_AUTO_OFF) {
spin_lock_irqsave(&clocks_lock, flags);
if (!clk->count) {
count++;
pc_clk_disable(clk->id);
}
spin_unlock_irqrestore(&clocks_lock, flags);
}
}
mutex_unlock(&clocks_mutex);
pr_info("clock_late_init() disabled %d unused clocks\n", count);
return 0;
}
late_initcall(clock_late_init);

48
arch/arm/mach-msm/clock.h Normal file
View file

@ -0,0 +1,48 @@
/* arch/arm/mach-msm/clock.h
*
* Copyright (C) 2007 Google, Inc.
* Copyright (c) 2007 QUALCOMM Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ARCH_ARM_MACH_MSM_CLOCK_H
#define __ARCH_ARM_MACH_MSM_CLOCK_H
#include <linux/list.h>
#define CLKFLAG_INVERT 0x00000001
#define CLKFLAG_NOINVERT 0x00000002
#define CLKFLAG_NONEST 0x00000004
#define CLKFLAG_NORESET 0x00000008
#define CLK_FIRST_AVAILABLE_FLAG 0x00000100
#define CLKFLAG_USE_MIN_MAX_TO_SET 0x00000200
#define CLKFLAG_AUTO_OFF 0x00000400
struct clk {
uint32_t id;
uint32_t count;
uint32_t flags;
const char *name;
struct list_head list;
struct device *dev;
};
#define A11S_CLK_CNTL_ADDR (MSM_CSR_BASE + 0x100)
#define A11S_CLK_SEL_ADDR (MSM_CSR_BASE + 0x104)
#define A11S_VDD_SVS_PLEVEL_ADDR (MSM_CSR_BASE + 0x124)
extern struct clk msm_clocks[];
extern unsigned msm_num_clocks;
#endif

View file

@ -1,116 +0,0 @@
/* linux/arch/arm/mach-msm/common.c
*
* Common setup code for MSM7K Boards
*
* Copyright (C) 2007 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <asm/mach/flash.h>
#include <asm/setup.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <mach/msm_iomap.h>
#include <mach/board.h>
struct flash_platform_data msm_nand_data = {
.parts = 0,
.nr_parts = 0,
};
static struct resource msm_nand_resources[] = {
[0] = {
.start = 7,
.end = 7,
.flags = IORESOURCE_DMA,
},
};
static struct platform_device msm_nand_device = {
.name = "msm_nand",
.id = -1,
.num_resources = ARRAY_SIZE(msm_nand_resources),
.resource = msm_nand_resources,
.dev = {
.platform_data = &msm_nand_data,
},
};
static struct platform_device msm_smd_device = {
.name = "msm_smd",
.id = -1,
};
static struct resource msm_i2c_resources[] = {
{
.start = MSM_I2C_BASE,
.end = MSM_I2C_BASE + MSM_I2C_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_PWB_I2C,
.end = INT_PWB_I2C,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device msm_i2c_device = {
.name = "msm_i2c",
.id = 0,
.num_resources = ARRAY_SIZE(msm_i2c_resources),
.resource = msm_i2c_resources,
};
static struct resource usb_resources[] = {
{
.start = MSM_HSUSB_PHYS,
.end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = INT_USB_HS,
.end = INT_USB_HS,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device msm_hsusb_device = {
.name = "msm_hsusb",
.id = -1,
.num_resources = ARRAY_SIZE(usb_resources),
.resource = usb_resources,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
static struct platform_device *devices[] __initdata = {
&msm_nand_device,
&msm_smd_device,
&msm_i2c_device,
&msm_hsusb_device,
};
void __init msm_add_devices(void)
{
platform_add_devices(devices, ARRAY_SIZE(devices));
}

267
arch/arm/mach-msm/devices.c Normal file
View file

@ -0,0 +1,267 @@
/* linux/arch/arm/mach-msm/devices.c
*
* Copyright (C) 2008 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <mach/msm_iomap.h>
#include "devices.h"
#include <asm/mach/flash.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
static struct resource resources_uart1[] = {
{
.start = INT_UART1,
.end = INT_UART1,
.flags = IORESOURCE_IRQ,
},
{
.start = MSM_UART1_PHYS,
.end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
static struct resource resources_uart2[] = {
{
.start = INT_UART2,
.end = INT_UART2,
.flags = IORESOURCE_IRQ,
},
{
.start = MSM_UART2_PHYS,
.end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
static struct resource resources_uart3[] = {
{
.start = INT_UART3,
.end = INT_UART3,
.flags = IORESOURCE_IRQ,
},
{
.start = MSM_UART3_PHYS,
.end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1,
.flags = IORESOURCE_MEM,
},
};
struct platform_device msm_device_uart1 = {
.name = "msm_serial",
.id = 0,
.num_resources = ARRAY_SIZE(resources_uart1),
.resource = resources_uart1,
};
struct platform_device msm_device_uart2 = {
.name = "msm_serial",
.id = 1,
.num_resources = ARRAY_SIZE(resources_uart2),
.resource = resources_uart2,
};
struct platform_device msm_device_uart3 = {
.name = "msm_serial",
.id = 2,
.num_resources = ARRAY_SIZE(resources_uart3),
.resource = resources_uart3,
};
static struct resource resources_i2c[] = {
{
.start = MSM_I2C_PHYS,
.end = MSM_I2C_PHYS + MSM_I2C_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_PWB_I2C,
.end = INT_PWB_I2C,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_i2c = {
.name = "msm_i2c",
.id = 0,
.num_resources = ARRAY_SIZE(resources_i2c),
.resource = resources_i2c,
};
static struct resource resources_hsusb[] = {
{
.start = MSM_HSUSB_PHYS,
.end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE,
.flags = IORESOURCE_MEM,
},
{
.start = INT_USB_HS,
.end = INT_USB_HS,
.flags = IORESOURCE_IRQ,
},
};
struct platform_device msm_device_hsusb = {
.name = "msm_hsusb",
.id = -1,
.num_resources = ARRAY_SIZE(resources_hsusb),
.resource = resources_hsusb,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct flash_platform_data msm_nand_data = {
.parts = NULL,
.nr_parts = 0,
};
static struct resource resources_nand[] = {
[0] = {
.start = 7,
.end = 7,
.flags = IORESOURCE_DMA,
},
};
struct platform_device msm_device_nand = {
.name = "msm_nand",
.id = -1,
.num_resources = ARRAY_SIZE(resources_nand),
.resource = resources_nand,
.dev = {
.platform_data = &msm_nand_data,
},
};
struct platform_device msm_device_smd = {
.name = "msm_smd",
.id = -1,
};
static struct resource resources_sdc1[] = {
{
.start = MSM_SDC1_PHYS,
.end = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC1_0,
.end = INT_SDC1_1,
.flags = IORESOURCE_IRQ,
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
static struct resource resources_sdc2[] = {
{
.start = MSM_SDC2_PHYS,
.end = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC2_0,
.end = INT_SDC2_1,
.flags = IORESOURCE_IRQ,
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
static struct resource resources_sdc3[] = {
{
.start = MSM_SDC3_PHYS,
.end = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC3_0,
.end = INT_SDC3_1,
.flags = IORESOURCE_IRQ,
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
static struct resource resources_sdc4[] = {
{
.start = MSM_SDC4_PHYS,
.end = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1,
.flags = IORESOURCE_MEM,
},
{
.start = INT_SDC4_0,
.end = INT_SDC4_1,
.flags = IORESOURCE_IRQ,
},
{
.start = 8,
.end = 8,
.flags = IORESOURCE_DMA,
},
};
struct platform_device msm_device_sdc1 = {
.name = "msm_sdcc",
.id = 1,
.num_resources = ARRAY_SIZE(resources_sdc1),
.resource = resources_sdc1,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct platform_device msm_device_sdc2 = {
.name = "msm_sdcc",
.id = 2,
.num_resources = ARRAY_SIZE(resources_sdc2),
.resource = resources_sdc2,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct platform_device msm_device_sdc3 = {
.name = "msm_sdcc",
.id = 3,
.num_resources = ARRAY_SIZE(resources_sdc3),
.resource = resources_sdc3,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};
struct platform_device msm_device_sdc4 = {
.name = "msm_sdcc",
.id = 4,
.num_resources = ARRAY_SIZE(resources_sdc4),
.resource = resources_sdc4,
.dev = {
.coherent_dma_mask = 0xffffffff,
},
};

View file

@ -0,0 +1,36 @@
/* linux/arch/arm/mach-msm/devices.h
*
* Copyright (C) 2008 Google, Inc.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ARCH_ARM_MACH_MSM_DEVICES_H
#define __ARCH_ARM_MACH_MSM_DEVICES_H
extern struct platform_device msm_device_uart1;
extern struct platform_device msm_device_uart2;
extern struct platform_device msm_device_uart3;
extern struct platform_device msm_device_sdc1;
extern struct platform_device msm_device_sdc2;
extern struct platform_device msm_device_sdc3;
extern struct platform_device msm_device_sdc4;
extern struct platform_device msm_device_hsusb;
extern struct platform_device msm_device_i2c;
extern struct platform_device msm_device_smd;
extern struct platform_device msm_device_nand;
#endif

View file

@ -26,7 +26,7 @@ enum {
};
static DEFINE_SPINLOCK(msm_dmov_lock);
static struct msm_dmov_cmd active_command;
static unsigned int channel_active;
static struct list_head ready_commands[MSM_DMOV_CHANNEL_COUNT];
static struct list_head active_commands[MSM_DMOV_CHANNEL_COUNT];
unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
@ -43,6 +43,11 @@ unsigned int msm_dmov_print_mask = MSM_DMOV_PRINT_ERRORS;
#define PRINT_FLOW(format, args...) \
MSM_DMOV_DPRINTF(MSM_DMOV_PRINT_FLOW, format, args);
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful)
{
writel((graceful << 31), DMOV_FLUSH0(id));
}
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
{
unsigned long irq_flags;
@ -60,6 +65,9 @@ void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd)
#endif
PRINT_IO("msm_dmov_enqueue_cmd(%d), start command, status %x\n", id, status);
list_add_tail(&cmd->list, &active_commands[id]);
if (!channel_active)
enable_irq(INT_ADM_AARM);
channel_active |= 1U << id;
writel(cmd->cmdptr, DMOV_CMD_PTR(id));
} else {
if (list_empty(&active_commands[id]))
@ -76,21 +84,19 @@ struct msm_dmov_exec_cmdptr_cmd {
struct completion complete;
unsigned id;
unsigned int result;
unsigned int flush[6];
struct msm_dmov_errdata err;
};
static void dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd, unsigned int result)
static void
dmov_exec_cmdptr_complete_func(struct msm_dmov_cmd *_cmd,
unsigned int result,
struct msm_dmov_errdata *err)
{
struct msm_dmov_exec_cmdptr_cmd *cmd = container_of(_cmd, struct msm_dmov_exec_cmdptr_cmd, dmov_cmd);
cmd->result = result;
if (result != 0x80000002) {
cmd->flush[0] = readl(DMOV_FLUSH0(cmd->id));
cmd->flush[1] = readl(DMOV_FLUSH1(cmd->id));
cmd->flush[2] = readl(DMOV_FLUSH2(cmd->id));
cmd->flush[3] = readl(DMOV_FLUSH3(cmd->id));
cmd->flush[4] = readl(DMOV_FLUSH4(cmd->id));
cmd->flush[5] = readl(DMOV_FLUSH5(cmd->id));
}
if (result != 0x80000002 && err)
memcpy(&cmd->err, err, sizeof(struct msm_dmov_errdata));
complete(&cmd->complete);
}
@ -111,7 +117,7 @@ int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr)
if (cmd.result != 0x80000002) {
PRINT_ERROR("dmov_exec_cmdptr(%d): ERROR, result: %x\n", id, cmd.result);
PRINT_ERROR("dmov_exec_cmdptr(%d): flush: %x %x %x %x\n",
id, cmd.flush[0], cmd.flush[1], cmd.flush[2], cmd.flush[3]);
id, cmd.err.flush[0], cmd.err.flush[1], cmd.err.flush[2], cmd.err.flush[3]);
return -EIO;
}
PRINT_FLOW("dmov_exec_cmdptr(%d, %x) done\n", id, cmdptr);
@ -159,25 +165,40 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
"for %p, result %x\n", id, cmd, ch_result);
if (cmd) {
list_del(&cmd->list);
cmd->complete_func(cmd, ch_result);
cmd->complete_func(cmd, ch_result, NULL);
}
}
if (ch_result & DMOV_RSLT_FLUSH) {
unsigned int flush0 = readl(DMOV_FLUSH0(id));
struct msm_dmov_errdata errdata;
errdata.flush[0] = readl(DMOV_FLUSH0(id));
errdata.flush[1] = readl(DMOV_FLUSH1(id));
errdata.flush[2] = readl(DMOV_FLUSH2(id));
errdata.flush[3] = readl(DMOV_FLUSH3(id));
errdata.flush[4] = readl(DMOV_FLUSH4(id));
errdata.flush[5] = readl(DMOV_FLUSH5(id));
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, flush0);
PRINT_FLOW("msm_datamover_irq_handler id %d, flush, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
if (cmd) {
list_del(&cmd->list);
cmd->complete_func(cmd, ch_result);
cmd->complete_func(cmd, ch_result, &errdata);
}
}
if (ch_result & DMOV_RSLT_ERROR) {
unsigned int flush0 = readl(DMOV_FLUSH0(id));
struct msm_dmov_errdata errdata;
errdata.flush[0] = readl(DMOV_FLUSH0(id));
errdata.flush[1] = readl(DMOV_FLUSH1(id));
errdata.flush[2] = readl(DMOV_FLUSH2(id));
errdata.flush[3] = readl(DMOV_FLUSH3(id));
errdata.flush[4] = readl(DMOV_FLUSH4(id));
errdata.flush[5] = readl(DMOV_FLUSH5(id));
PRINT_ERROR("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, flush0);
PRINT_ERROR("msm_datamover_irq_handler id %d, error, result %x, flush0 %x\n", id, ch_result, errdata.flush[0]);
if (cmd) {
list_del(&cmd->list);
cmd->complete_func(cmd, ch_result);
cmd->complete_func(cmd, ch_result, &errdata);
}
/* this does not seem to work, once we get an error */
/* the datamover will no longer accept commands */
@ -193,8 +214,14 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
writel(cmd->cmdptr, DMOV_CMD_PTR(id));
}
} while (ch_status & DMOV_STATUS_RSLT_VALID);
if (list_empty(&active_commands[id]) && list_empty(&ready_commands[id]))
channel_active &= ~(1U << id);
PRINT_FLOW("msm_datamover_irq_handler id %d, status %x\n", id, ch_status);
}
if (!channel_active)
disable_irq(INT_ADM_AARM);
spin_unlock_irqrestore(&msm_dmov_lock, irq_flags);
return IRQ_HANDLED;
}
@ -202,12 +229,17 @@ static irqreturn_t msm_datamover_irq_handler(int irq, void *dev_id)
static int __init msm_init_datamover(void)
{
int i;
int ret;
for (i = 0; i < MSM_DMOV_CHANNEL_COUNT; i++) {
INIT_LIST_HEAD(&ready_commands[i]);
INIT_LIST_HEAD(&active_commands[i]);
writel(DMOV_CONFIG_IRQ_EN | DMOV_CONFIG_FORCE_TOP_PTR_RSLT | DMOV_CONFIG_FORCE_FLUSH_RSLT, DMOV_CONFIG(i));
}
return request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
ret = request_irq(INT_ADM_AARM, msm_datamover_irq_handler, 0, "msmdatamover", NULL);
if (ret)
return ret;
disable_irq(INT_ADM_AARM);
return 0;
}
arch_initcall(msm_init_datamover);

View file

@ -33,5 +33,6 @@ void __init msm_add_devices(void);
void __init msm_map_common_io(void);
void __init msm_init_irq(void);
void __init msm_init_gpio(void);
void __init msm_clock_init(void);
#endif

View file

@ -22,18 +22,22 @@
mrc p15, 0, \rx, c1, c0
tst \rx, #1
ldreq \rx, =MSM_UART1_PHYS
ldrne \rx, =MSM_UART1_BASE
movne \rx, #0
.endm
.macro senduart,rd,rx
str \rd, [\rx, #0x0C]
teq \rx, #0
strne \rd, [\rx, #0x0C]
.endm
.macro waituart,rd,rx
@ wait for TX_READY
teq \rx, #0
bne 2f
1: ldr \rd, [\rx, #0x08]
tst \rd, #0x04
beq 1b
2:
.endm
.macro busyuart,rd,rx

View file

@ -1,4 +1,4 @@
/* arch/arm/mach-msm/include/mach/dma.h
/* linux/include/asm-arm/arch-msm/dma.h
*
* Copyright (C) 2007 Google, Inc.
*
@ -18,17 +18,21 @@
#include <linux/list.h>
#include <mach/msm_iomap.h>
struct msm_dmov_errdata {
uint32_t flush[6];
};
struct msm_dmov_cmd {
struct list_head list;
unsigned int cmdptr;
void (*complete_func)(struct msm_dmov_cmd *cmd, unsigned int result);
/* void (*user_result_func)(struct msm_dmov_cmd *cmd); */
void (*complete_func)(struct msm_dmov_cmd *cmd,
unsigned int result,
struct msm_dmov_errdata *err);
};
void msm_dmov_enqueue_cmd(unsigned id, struct msm_dmov_cmd *cmd);
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd);
void msm_dmov_stop_cmd(unsigned id, struct msm_dmov_cmd *cmd, int graceful);
int msm_dmov_exec_cmd(unsigned id, unsigned int cmdptr);
/* int msm_dmov_exec_cmd_etc(unsigned id, unsigned int cmdptr, int timeout, int interruptible); */
@ -122,6 +126,16 @@ typedef struct {
unsigned _reserved;
} dmov_sg;
/* Box mode */
typedef struct {
uint32_t cmd;
uint32_t src_row_addr;
uint32_t dst_row_addr;
uint32_t src_dst_len;
uint32_t num_rows;
uint32_t row_offset;
} dmov_box;
/* bits for the cmd field of the above structures */
#define CMD_LC (1 << 31) /* last command */

View file

@ -37,11 +37,17 @@
*
*/
#define MSM_VIC_BASE 0xE0000000
#ifdef __ASSEMBLY__
#define IOMEM(x) x
#else
#define IOMEM(x) ((void __force __iomem *)(x))
#endif
#define MSM_VIC_BASE IOMEM(0xE0000000)
#define MSM_VIC_PHYS 0xC0000000
#define MSM_VIC_SIZE SZ_4K
#define MSM_CSR_BASE 0xE0001000
#define MSM_CSR_BASE IOMEM(0xE0001000)
#define MSM_CSR_PHYS 0xC0100000
#define MSM_CSR_SIZE SZ_4K
@ -49,56 +55,67 @@
#define MSM_GPT_BASE MSM_CSR_BASE
#define MSM_GPT_SIZE SZ_4K
#define MSM_DMOV_BASE 0xE0002000
#define MSM_DMOV_BASE IOMEM(0xE0002000)
#define MSM_DMOV_PHYS 0xA9700000
#define MSM_DMOV_SIZE SZ_4K
#define MSM_UART1_BASE 0xE0003000
#define MSM_UART1_PHYS 0xA9A00000
#define MSM_UART1_SIZE SZ_4K
#define MSM_UART2_BASE 0xE0004000
#define MSM_UART2_PHYS 0xA9B00000
#define MSM_UART2_SIZE SZ_4K
#define MSM_UART3_BASE 0xE0005000
#define MSM_UART3_PHYS 0xA9C00000
#define MSM_UART3_SIZE SZ_4K
#define MSM_I2C_BASE 0xE0006000
#define MSM_I2C_PHYS 0xA9900000
#define MSM_I2C_SIZE SZ_4K
#define MSM_GPIO1_BASE 0xE0007000
#define MSM_GPIO1_BASE IOMEM(0xE0003000)
#define MSM_GPIO1_PHYS 0xA9200000
#define MSM_GPIO1_SIZE SZ_4K
#define MSM_GPIO2_BASE 0xE0008000
#define MSM_GPIO2_BASE IOMEM(0xE0004000)
#define MSM_GPIO2_PHYS 0xA9300000
#define MSM_GPIO2_SIZE SZ_4K
#define MSM_HSUSB_BASE 0xE0009000
#define MSM_HSUSB_PHYS 0xA0800000
#define MSM_HSUSB_SIZE SZ_4K
#define MSM_CLK_CTL_BASE 0xE000A000
#define MSM_CLK_CTL_BASE IOMEM(0xE0005000)
#define MSM_CLK_CTL_PHYS 0xA8600000
#define MSM_CLK_CTL_SIZE SZ_4K
#define MSM_PMDH_BASE 0xE000B000
#define MSM_PMDH_PHYS 0xAA600000
#define MSM_PMDH_SIZE SZ_4K
#define MSM_EMDH_BASE 0xE000C000
#define MSM_EMDH_PHYS 0xAA700000
#define MSM_EMDH_SIZE SZ_4K
#define MSM_MDP_BASE 0xE0010000
#define MSM_MDP_PHYS 0xAA200000
#define MSM_MDP_SIZE 0x000F0000
#define MSM_SHARED_RAM_BASE 0xE0100000
#define MSM_SHARED_RAM_BASE IOMEM(0xE0100000)
#define MSM_SHARED_RAM_PHYS 0x01F00000
#define MSM_SHARED_RAM_SIZE SZ_1M
#define MSM_UART1_PHYS 0xA9A00000
#define MSM_UART1_SIZE SZ_4K
#define MSM_UART2_PHYS 0xA9B00000
#define MSM_UART2_SIZE SZ_4K
#define MSM_UART3_PHYS 0xA9C00000
#define MSM_UART3_SIZE SZ_4K
#define MSM_SDC1_PHYS 0xA0400000
#define MSM_SDC1_SIZE SZ_4K
#define MSM_SDC2_PHYS 0xA0500000
#define MSM_SDC2_SIZE SZ_4K
#define MSM_SDC3_PHYS 0xA0600000
#define MSM_SDC3_SIZE SZ_4K
#define MSM_SDC4_PHYS 0xA0700000
#define MSM_SDC4_SIZE SZ_4K
#define MSM_I2C_PHYS 0xA9900000
#define MSM_I2C_SIZE SZ_4K
#define MSM_HSUSB_PHYS 0xA0800000
#define MSM_HSUSB_SIZE SZ_4K
#define MSM_PMDH_PHYS 0xAA600000
#define MSM_PMDH_SIZE SZ_4K
#define MSM_EMDH_PHYS 0xAA700000
#define MSM_EMDH_SIZE SZ_4K
#define MSM_MDP_PHYS 0xAA200000
#define MSM_MDP_SIZE 0x000F0000
#define MSM_MDC_PHYS 0xAA500000
#define MSM_MDC_SIZE SZ_1M
#define MSM_AD5_PHYS 0xAC000000
#define MSM_AD5_SIZE (SZ_1M*13)
#endif

View file

@ -0,0 +1,29 @@
/* linux/include/asm-arm/arch-msm/vreg.h
*
* Copyright (C) 2008 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef __ARCH_ARM_MACH_MSM_VREG_H
#define __ARCH_ARM_MACH_MSM_VREG_H
struct vreg;
struct vreg *vreg_get(struct device *dev, const char *id);
void vreg_put(struct vreg *vreg);
int vreg_enable(struct vreg *vreg);
void vreg_disable(struct vreg *vreg);
int vreg_set_level(struct vreg *vreg, unsigned mv);
#endif

View file

@ -28,7 +28,7 @@
#include <mach/board.h>
#define MSM_DEVICE(name) { \
.virtual = MSM_##name##_BASE, \
.virtual = (unsigned long) MSM_##name##_BASE, \
.pfn = __phys_to_pfn(MSM_##name##_PHYS), \
.length = MSM_##name##_SIZE, \
.type = MT_DEVICE_NONSHARED, \
@ -39,19 +39,11 @@ static struct map_desc msm_io_desc[] __initdata = {
MSM_DEVICE(CSR),
MSM_DEVICE(GPT),
MSM_DEVICE(DMOV),
MSM_DEVICE(UART1),
MSM_DEVICE(UART2),
MSM_DEVICE(UART3),
MSM_DEVICE(I2C),
MSM_DEVICE(GPIO1),
MSM_DEVICE(GPIO2),
MSM_DEVICE(HSUSB),
MSM_DEVICE(CLK_CTL),
MSM_DEVICE(PMDH),
MSM_DEVICE(EMDH),
MSM_DEVICE(MDP),
{
.virtual = MSM_SHARED_RAM_BASE,
.virtual = (unsigned long) MSM_SHARED_RAM_BASE,
.pfn = __phys_to_pfn(MSM_SHARED_RAM_PHYS),
.length = MSM_SHARED_RAM_SIZE,
.type = MT_DEVICE,

View file

@ -66,20 +66,20 @@
static void msm_irq_ack(unsigned int irq)
{
unsigned reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0);
void __iomem *reg = VIC_INT_CLEAR0 + ((irq & 32) ? 4 : 0);
irq = 1 << (irq & 31);
writel(irq, reg);
}
static void msm_irq_mask(unsigned int irq)
{
unsigned reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0);
void __iomem *reg = VIC_INT_ENCLEAR0 + ((irq & 32) ? 4 : 0);
writel(1 << (irq & 31), reg);
}
static void msm_irq_unmask(unsigned int irq)
{
unsigned reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0);
void __iomem *reg = VIC_INT_ENSET0 + ((irq & 32) ? 4 : 0);
writel(1 << (irq & 31), reg);
}
@ -90,8 +90,8 @@ static int msm_irq_set_wake(unsigned int irq, unsigned int on)
static int msm_irq_set_type(unsigned int irq, unsigned int flow_type)
{
unsigned treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0);
unsigned preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0);
void __iomem *treg = VIC_INT_TYPE0 + ((irq & 32) ? 4 : 0);
void __iomem *preg = VIC_INT_POLARITY0 + ((irq & 32) ? 4 : 0);
int b = 1 << (irq & 31);
if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))

View file

@ -0,0 +1,110 @@
/* arch/arm/mach-msm/proc_comm.c
*
* Copyright (C) 2007-2008 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/spinlock.h>
#include <mach/msm_iomap.h>
#include <mach/system.h>
#include "proc_comm.h"
#define MSM_A2M_INT(n) (MSM_CSR_BASE + 0x400 + (n) * 4)
static inline void notify_other_proc_comm(void)
{
writel(1, MSM_A2M_INT(6));
}
#define APP_COMMAND 0x00
#define APP_STATUS 0x04
#define APP_DATA1 0x08
#define APP_DATA2 0x0C
#define MDM_COMMAND 0x10
#define MDM_STATUS 0x14
#define MDM_DATA1 0x18
#define MDM_DATA2 0x1C
static DEFINE_SPINLOCK(proc_comm_lock);
/* The higher level SMD support will install this to
* provide a way to check for and handle modem restart.
*/
int (*msm_check_for_modem_crash)(void);
/* Poll for a state change, checking for possible
* modem crashes along the way (so we don't wait
* forever while the ARM9 is blowing up).
*
* Return an error in the event of a modem crash and
* restart so the msm_proc_comm() routine can restart
* the operation from the beginning.
*/
static int proc_comm_wait_for(void __iomem *addr, unsigned value)
{
for (;;) {
if (readl(addr) == value)
return 0;
if (msm_check_for_modem_crash)
if (msm_check_for_modem_crash())
return -EAGAIN;
}
}
int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2)
{
void __iomem *base = MSM_SHARED_RAM_BASE;
unsigned long flags;
int ret;
spin_lock_irqsave(&proc_comm_lock, flags);
for (;;) {
if (proc_comm_wait_for(base + MDM_STATUS, PCOM_READY))
continue;
writel(cmd, base + APP_COMMAND);
writel(data1 ? *data1 : 0, base + APP_DATA1);
writel(data2 ? *data2 : 0, base + APP_DATA2);
notify_other_proc_comm();
if (proc_comm_wait_for(base + APP_COMMAND, PCOM_CMD_DONE))
continue;
if (readl(base + APP_STATUS) != PCOM_CMD_FAIL) {
if (data1)
*data1 = readl(base + APP_DATA1);
if (data2)
*data2 = readl(base + APP_DATA2);
ret = 0;
} else {
ret = -EIO;
}
break;
}
writel(PCOM_CMD_IDLE, base + APP_COMMAND);
spin_unlock_irqrestore(&proc_comm_lock, flags);
return ret;
}

View file

@ -0,0 +1,165 @@
/* arch/arm/mach-msm/proc_comm.h
*
* Copyright (c) 2007 QUALCOMM Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef _ARCH_ARM_MACH_MSM_PROC_COMM_H_
#define _ARCH_ARM_MACH_MSM_PROC_COMM_H_
enum {
PCOM_CMD_IDLE = 0x0,
PCOM_CMD_DONE,
PCOM_RESET_APPS,
PCOM_RESET_CHIP,
PCOM_CONFIG_NAND_MPU,
PCOM_CONFIG_USB_CLKS,
PCOM_GET_POWER_ON_STATUS,
PCOM_GET_WAKE_UP_STATUS,
PCOM_GET_BATT_LEVEL,
PCOM_CHG_IS_CHARGING,
PCOM_POWER_DOWN,
PCOM_USB_PIN_CONFIG,
PCOM_USB_PIN_SEL,
PCOM_SET_RTC_ALARM,
PCOM_NV_READ,
PCOM_NV_WRITE,
PCOM_GET_UUID_HIGH,
PCOM_GET_UUID_LOW,
PCOM_GET_HW_ENTROPY,
PCOM_RPC_GPIO_TLMM_CONFIG_REMOTE,
PCOM_CLKCTL_RPC_ENABLE,
PCOM_CLKCTL_RPC_DISABLE,
PCOM_CLKCTL_RPC_RESET,
PCOM_CLKCTL_RPC_SET_FLAGS,
PCOM_CLKCTL_RPC_SET_RATE,
PCOM_CLKCTL_RPC_MIN_RATE,
PCOM_CLKCTL_RPC_MAX_RATE,
PCOM_CLKCTL_RPC_RATE,
PCOM_CLKCTL_RPC_PLL_REQUEST,
PCOM_CLKCTL_RPC_ENABLED,
PCOM_VREG_SWITCH,
PCOM_VREG_SET_LEVEL,
PCOM_GPIO_TLMM_CONFIG_GROUP,
PCOM_GPIO_TLMM_UNCONFIG_GROUP,
PCOM_NV_WRITE_BYTES_4_7,
PCOM_CONFIG_DISP,
PCOM_GET_FTM_BOOT_COUNT,
PCOM_RPC_GPIO_TLMM_CONFIG_EX,
PCOM_PM_MPP_CONFIG,
PCOM_GPIO_IN,
PCOM_GPIO_OUT,
PCOM_RESET_MODEM,
PCOM_RESET_CHIP_IMM,
PCOM_PM_VID_EN,
PCOM_VREG_PULLDOWN,
PCOM_NUM_CMDS,
};
enum {
PCOM_INVALID_STATUS = 0x0,
PCOM_READY,
PCOM_CMD_RUNNING,
PCOM_CMD_SUCCESS,
PCOM_CMD_FAIL,
};
/* List of VREGs that support the Pull Down Resistor setting. */
enum {
PM_VREG_PDOWN_MSMA_ID,
PM_VREG_PDOWN_MSMP_ID,
PM_VREG_PDOWN_MSME1_ID, /* Not supported in Panoramix */
PM_VREG_PDOWN_MSMC1_ID, /* Not supported in PM6620 */
PM_VREG_PDOWN_MSMC2_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_GP3_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_MSME2_ID, /* Supported in PM7500 and Panoramix only */
PM_VREG_PDOWN_GP4_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_GP1_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_TCXO_ID,
PM_VREG_PDOWN_PA_ID,
PM_VREG_PDOWN_RFTX_ID,
PM_VREG_PDOWN_RFRX1_ID,
PM_VREG_PDOWN_RFRX2_ID,
PM_VREG_PDOWN_SYNT_ID,
PM_VREG_PDOWN_WLAN_ID,
PM_VREG_PDOWN_USB_ID,
PM_VREG_PDOWN_MMC_ID,
PM_VREG_PDOWN_RUIM_ID,
PM_VREG_PDOWN_MSMC0_ID, /* Supported in PM6610 only */
PM_VREG_PDOWN_GP2_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_GP5_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_GP6_ID, /* Supported in PM7500 only */
PM_VREG_PDOWN_RF_ID,
PM_VREG_PDOWN_RF_VCO_ID,
PM_VREG_PDOWN_MPLL_ID,
PM_VREG_PDOWN_S2_ID,
PM_VREG_PDOWN_S3_ID,
PM_VREG_PDOWN_RFUBM_ID,
/* new for HAN */
PM_VREG_PDOWN_RF1_ID,
PM_VREG_PDOWN_RF2_ID,
PM_VREG_PDOWN_RFA_ID,
PM_VREG_PDOWN_CDC2_ID,
PM_VREG_PDOWN_RFTX2_ID,
PM_VREG_PDOWN_USIM_ID,
PM_VREG_PDOWN_USB2P6_ID,
PM_VREG_PDOWN_USB3P3_ID,
PM_VREG_PDOWN_INVALID_ID,
/* backward compatible enums only */
PM_VREG_PDOWN_CAM_ID = PM_VREG_PDOWN_GP1_ID,
PM_VREG_PDOWN_MDDI_ID = PM_VREG_PDOWN_GP2_ID,
PM_VREG_PDOWN_RUIM2_ID = PM_VREG_PDOWN_GP3_ID,
PM_VREG_PDOWN_AUX_ID = PM_VREG_PDOWN_GP4_ID,
PM_VREG_PDOWN_AUX2_ID = PM_VREG_PDOWN_GP5_ID,
PM_VREG_PDOWN_BT_ID = PM_VREG_PDOWN_GP6_ID,
PM_VREG_PDOWN_MSME_ID = PM_VREG_PDOWN_MSME1_ID,
PM_VREG_PDOWN_MSMC_ID = PM_VREG_PDOWN_MSMC1_ID,
PM_VREG_PDOWN_RFA1_ID = PM_VREG_PDOWN_RFRX2_ID,
PM_VREG_PDOWN_RFA2_ID = PM_VREG_PDOWN_RFTX2_ID,
PM_VREG_PDOWN_XO_ID = PM_VREG_PDOWN_TCXO_ID
};
/* gpio info for PCOM_RPC_GPIO_TLMM_CONFIG_EX */
#define GPIO_ENABLE 0
#define GPIO_DISABLE 1
#define GPIO_INPUT 0
#define GPIO_OUTPUT 1
#define GPIO_NO_PULL 0
#define GPIO_PULL_DOWN 1
#define GPIO_KEEPER 2
#define GPIO_PULL_UP 3
#define GPIO_2MA 0
#define GPIO_4MA 1
#define GPIO_6MA 2
#define GPIO_8MA 3
#define GPIO_10MA 4
#define GPIO_12MA 5
#define GPIO_14MA 6
#define GPIO_16MA 7
#define PCOM_GPIO_CFG(gpio, func, dir, pull, drvstr) \
((((gpio) & 0x3FF) << 4) | \
((func) & 0xf) | \
(((dir) & 0x1) << 14) | \
(((pull) & 0x3) << 15) | \
(((drvstr) & 0xF) << 17))
int msm_proc_comm(unsigned cmd, unsigned *data1, unsigned *data2);
#endif

View file

@ -45,7 +45,7 @@ struct msm_clock {
struct clock_event_device clockevent;
struct clocksource clocksource;
struct irqaction irq;
uint32_t regbase;
void __iomem *regbase;
uint32_t freq;
uint32_t shift;
};

143
arch/arm/mach-msm/vreg.c Normal file
View file

@ -0,0 +1,143 @@
/* arch/arm/mach-msm/vreg.c
*
* Copyright (C) 2008 Google, Inc.
* Author: Brian Swetland <swetland@google.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/debugfs.h>
#include <mach/vreg.h>
#include "proc_comm.h"
struct vreg {
const char *name;
unsigned id;
};
#define VREG(_name, _id) { .name = _name, .id = _id, }
static struct vreg vregs[] = {
VREG("msma", 0),
VREG("msmp", 1),
VREG("msme1", 2),
VREG("msmc1", 3),
VREG("msmc2", 4),
VREG("gp3", 5),
VREG("msme2", 6),
VREG("gp4", 7),
VREG("gp1", 8),
VREG("tcxo", 9),
VREG("pa", 10),
VREG("rftx", 11),
VREG("rfrx1", 12),
VREG("rfrx2", 13),
VREG("synt", 14),
VREG("wlan", 15),
VREG("usb", 16),
VREG("boost", 17),
VREG("mmc", 18),
VREG("ruim", 19),
VREG("msmc0", 20),
VREG("gp2", 21),
VREG("gp5", 22),
VREG("gp6", 23),
VREG("rf", 24),
VREG("rf_vco", 26),
VREG("mpll", 27),
VREG("s2", 28),
VREG("s3", 29),
VREG("rfubm", 30),
VREG("ncp", 31),
};
struct vreg *vreg_get(struct device *dev, const char *id)
{
int n;
for (n = 0; n < ARRAY_SIZE(vregs); n++) {
if (!strcmp(vregs[n].name, id))
return vregs + n;
}
return 0;
}
void vreg_put(struct vreg *vreg)
{
}
int vreg_enable(struct vreg *vreg)
{
unsigned id = vreg->id;
unsigned enable = 1;
return msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
}
void vreg_disable(struct vreg *vreg)
{
unsigned id = vreg->id;
unsigned enable = 0;
msm_proc_comm(PCOM_VREG_SWITCH, &id, &enable);
}
int vreg_set_level(struct vreg *vreg, unsigned mv)
{
unsigned id = vreg->id;
return msm_proc_comm(PCOM_VREG_SET_LEVEL, &id, &mv);
}
#if defined(CONFIG_DEBUG_FS)
static int vreg_debug_set(void *data, u64 val)
{
struct vreg *vreg = data;
switch (val) {
case 0:
vreg_disable(vreg);
break;
case 1:
vreg_enable(vreg);
break;
default:
vreg_set_level(vreg, val);
break;
}
return 0;
}
static int vreg_debug_get(void *data, u64 *val)
{
return -ENOSYS;
}
DEFINE_SIMPLE_ATTRIBUTE(vreg_fops, vreg_debug_get, vreg_debug_set, "%llu\n");
static int __init vreg_debug_init(void)
{
struct dentry *dent;
int n;
dent = debugfs_create_dir("vreg", 0);
if (IS_ERR(dent))
return 0;
for (n = 0; n < ARRAY_SIZE(vregs); n++)
(void) debugfs_create_file(vregs[n].name, 0644,
dent, vregs + n, &vreg_fops);
return 0;
}
device_initcall(vreg_debug_init);
#endif

View file

@ -13,6 +13,7 @@
#include <linux/platform_device.h>
#include <linux/ata_platform.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <mach/mv78xx0.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
@ -28,10 +29,14 @@ static struct mv643xx_eth_platform_data db78x00_ge01_data = {
static struct mv643xx_eth_platform_data db78x00_ge10_data = {
.phy_addr = MV643XX_ETH_PHY_NONE,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
};
static struct mv643xx_eth_platform_data db78x00_ge11_data = {
.phy_addr = MV643XX_ETH_PHY_NONE,
.speed = SPEED_1000,
.duplex = DUPLEX_FULL,
};
static struct mv_sata_platform_data db78x00_sata_data = {

View file

@ -19,6 +19,7 @@
#include <linux/mv643xx_i2c.h>
#include <linux/ata_platform.h>
#include <linux/spi/orion_spi.h>
#include <net/dsa.h>
#include <asm/page.h>
#include <asm/setup.h>
#include <asm/timex.h>
@ -197,6 +198,40 @@ void __init orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data)
}
/*****************************************************************************
* Ethernet switch
****************************************************************************/
static struct resource orion5x_switch_resources[] = {
{
.start = 0,
.end = 0,
.flags = IORESOURCE_IRQ,
},
};
static struct platform_device orion5x_switch_device = {
.name = "dsa",
.id = 0,
.num_resources = 0,
.resource = orion5x_switch_resources,
};
void __init orion5x_eth_switch_init(struct dsa_platform_data *d, int irq)
{
if (irq != NO_IRQ) {
orion5x_switch_resources[0].start = irq;
orion5x_switch_resources[0].end = irq;
orion5x_switch_device.num_resources = 1;
}
d->mii_bus = &orion5x_eth_shared.dev;
d->netdev = &orion5x_eth.dev;
orion5x_switch_device.dev.platform_data = d;
platform_device_register(&orion5x_switch_device);
}
/*****************************************************************************
* I2C
****************************************************************************/
@ -275,7 +310,8 @@ void __init orion5x_sata_init(struct mv_sata_platform_data *sata_data)
* SPI
****************************************************************************/
static struct orion_spi_info orion5x_spi_plat_data = {
.tclk = 0,
.tclk = 0,
.enable_clock_fix = 1,
};
static struct resource orion5x_spi_resources[] = {

View file

@ -1,6 +1,7 @@
#ifndef __ARCH_ORION5X_COMMON_H
#define __ARCH_ORION5X_COMMON_H
struct dsa_platform_data;
struct mv643xx_eth_platform_data;
struct mv_sata_platform_data;
@ -29,6 +30,7 @@ void orion5x_setup_pcie_wa_win(u32 base, u32 size);
void orion5x_ehci0_init(void);
void orion5x_ehci1_init(void);
void orion5x_eth_init(struct mv643xx_eth_platform_data *eth_data);
void orion5x_eth_switch_init(struct dsa_platform_data *d, int irq);
void orion5x_i2c_init(void);
void orion5x_sata_init(struct mv_sata_platform_data *sata_data);
void orion5x_spi_init(void);

View file

@ -16,6 +16,7 @@
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/leds.h>
@ -93,6 +94,15 @@ static struct mv643xx_eth_platform_data rd88f5181l_fxo_eth_data = {
.duplex = DUPLEX_FULL,
};
static struct dsa_platform_data rd88f5181l_fxo_switch_data = {
.port_names[0] = "lan2",
.port_names[1] = "lan1",
.port_names[2] = "wan",
.port_names[3] = "cpu",
.port_names[5] = "lan4",
.port_names[7] = "lan3",
};
static void __init rd88f5181l_fxo_init(void)
{
/*
@ -107,6 +117,7 @@ static void __init rd88f5181l_fxo_init(void)
*/
orion5x_ehci0_init();
orion5x_eth_init(&rd88f5181l_fxo_eth_data);
orion5x_eth_switch_init(&rd88f5181l_fxo_switch_data, NO_IRQ);
orion5x_uart0_init();
orion5x_setup_dev_boot_win(RD88F5181L_FXO_NOR_BOOT_BASE,

View file

@ -17,6 +17,7 @@
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <linux/i2c.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/leds.h>
@ -94,6 +95,15 @@ static struct mv643xx_eth_platform_data rd88f5181l_ge_eth_data = {
.duplex = DUPLEX_FULL,
};
static struct dsa_platform_data rd88f5181l_ge_switch_data = {
.port_names[0] = "lan2",
.port_names[1] = "lan1",
.port_names[2] = "wan",
.port_names[3] = "cpu",
.port_names[5] = "lan4",
.port_names[7] = "lan3",
};
static struct i2c_board_info __initdata rd88f5181l_ge_i2c_rtc = {
I2C_BOARD_INFO("ds1338", 0x68),
};
@ -112,6 +122,7 @@ static void __init rd88f5181l_ge_init(void)
*/
orion5x_ehci0_init();
orion5x_eth_init(&rd88f5181l_ge_eth_data);
orion5x_eth_switch_init(&rd88f5181l_ge_switch_data, gpio_to_irq(8));
orion5x_i2c_init();
orion5x_uart0_init();

View file

@ -19,6 +19,7 @@
#include <linux/spi/orion_spi.h>
#include <linux/spi/flash.h>
#include <linux/ethtool.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/leds.h>
@ -34,6 +35,15 @@ static struct mv643xx_eth_platform_data rd88f6183ap_ge_eth_data = {
.duplex = DUPLEX_FULL,
};
static struct dsa_platform_data rd88f6183ap_ge_switch_data = {
.port_names[0] = "lan1",
.port_names[1] = "lan2",
.port_names[2] = "lan3",
.port_names[3] = "lan4",
.port_names[4] = "wan",
.port_names[5] = "cpu",
};
static struct mtd_partition rd88f6183ap_ge_partitions[] = {
{
.name = "kernel",
@ -79,6 +89,7 @@ static void __init rd88f6183ap_ge_init(void)
*/
orion5x_ehci0_init();
orion5x_eth_init(&rd88f6183ap_ge_eth_data);
orion5x_eth_switch_init(&rd88f6183ap_ge_switch_data, gpio_to_irq(3));
spi_register_board_info(rd88f6183ap_ge_spi_slave_info,
ARRAY_SIZE(rd88f6183ap_ge_spi_slave_info));
orion5x_spi_init();

View file

@ -15,6 +15,7 @@
#include <linux/mtd/physmap.h>
#include <linux/mv643xx_eth.h>
#include <linux/ethtool.h>
#include <net/dsa.h>
#include <asm/mach-types.h>
#include <asm/gpio.h>
#include <asm/mach/arch.h>
@ -105,6 +106,15 @@ static struct mv643xx_eth_platform_data wrt350n_v2_eth_data = {
.duplex = DUPLEX_FULL,
};
static struct dsa_platform_data wrt350n_v2_switch_data = {
.port_names[0] = "lan2",
.port_names[1] = "lan1",
.port_names[2] = "wan",
.port_names[3] = "cpu",
.port_names[5] = "lan3",
.port_names[7] = "lan4",
};
static void __init wrt350n_v2_init(void)
{
/*
@ -119,6 +129,7 @@ static void __init wrt350n_v2_init(void)
*/
orion5x_ehci0_init();
orion5x_eth_init(&wrt350n_v2_eth_data);
orion5x_eth_switch_init(&wrt350n_v2_switch_data, NO_IRQ);
orion5x_uart0_init();
orion5x_setup_dev_boot_win(WRT350N_V2_NOR_BOOT_BASE,

View file

@ -71,6 +71,14 @@ config PXA_SHARPSL
SL-C3000 (Spitz), SL-C3100 (Borzoi) or SL-C6000x (Tosa)
handheld computer.
config CORGI_SSP_DEPRECATED
bool
select PXA_SSP
help
This option will include corgi_ssp.c and corgi_lcd.c
that corgi_ts.c and other legacy drivers (corgi_bl.c
and sharpsl_pm.c) may depend on.
config MACH_POODLE
bool "Enable Sharp SL-5600 (Poodle) Support"
depends on PXA_SHARPSL
@ -257,7 +265,6 @@ config MACH_ARMCORE
bool "CompuLab CM-X255/CM-X270 modules"
select PXA27x
select IWMMXT
select ZONE_DMA if PCI
select PXA25x
select PXA_SSP

View file

@ -37,6 +37,7 @@ obj-$(CONFIG_MACH_TRIZEPS4) += trizeps4.o
obj-$(CONFIG_MACH_COLIBRI) += colibri.o
obj-$(CONFIG_PXA_SHARP_C7xx) += corgi.o sharpsl_pm.o corgi_pm.o
obj-$(CONFIG_PXA_SHARP_Cxx00) += spitz.o sharpsl_pm.o spitz_pm.o
obj-$(CONFIG_CORGI_SSP_DEPRECATED) += corgi_ssp.o corgi_lcd.o
obj-$(CONFIG_MACH_POODLE) += poodle.o
obj-$(CONFIG_MACH_PCM027) += pcm027.o
obj-$(CONFIG_MACH_PCM990_BASEBOARD) += pcm990-baseboard.o

View file

@ -0,0 +1,289 @@
/*
* linux/arch/arm/mach-pxa/corgi_lcd.c
*
* Corgi/Spitz LCD Specific Code
*
* Copyright (C) 2005 Richard Purdie
*
* Connectivity:
* Corgi - LCD to ATI Imageon w100 (Wallaby)
* Spitz - LCD to PXA Framebuffer
*
* 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/delay.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/string.h>
#include <mach/corgi.h>
#include <mach/hardware.h>
#include <mach/pxa-regs.h>
#include <mach/sharpsl.h>
#include <mach/spitz.h>
#include <asm/hardware/scoop.h>
#include <asm/mach/sharpsl_param.h>
#include "generic.h"
/* Register Addresses */
#define RESCTL_ADRS 0x00
#define PHACTRL_ADRS 0x01
#define DUTYCTRL_ADRS 0x02
#define POWERREG0_ADRS 0x03
#define POWERREG1_ADRS 0x04
#define GPOR3_ADRS 0x05
#define PICTRL_ADRS 0x06
#define POLCTRL_ADRS 0x07
/* Register Bit Definitions */
#define RESCTL_QVGA 0x01
#define RESCTL_VGA 0x00
#define POWER1_VW_ON 0x01 /* VW Supply FET ON */
#define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */
#define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */
#define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */
#define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */
#define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */
#define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */
#define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */
#define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */
#define POWER0_COM_ON 0x08 /* COM Power Supply ON */
#define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */
#define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */
#define POWER0_COM_OFF 0x00 /* COM Power Supply OFF */
#define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */
#define PICTRL_INIT_STATE 0x01
#define PICTRL_INIOFF 0x02
#define PICTRL_POWER_DOWN 0x04
#define PICTRL_COM_SIGNAL_OFF 0x08
#define PICTRL_DAC_SIGNAL_OFF 0x10
#define POLCTRL_SYNC_POL_FALL 0x01
#define POLCTRL_EN_POL_FALL 0x02
#define POLCTRL_DATA_POL_FALL 0x04
#define POLCTRL_SYNC_ACT_H 0x08
#define POLCTRL_EN_ACT_L 0x10
#define POLCTRL_SYNC_POL_RISE 0x00
#define POLCTRL_EN_POL_RISE 0x00
#define POLCTRL_DATA_POL_RISE 0x00
#define POLCTRL_SYNC_ACT_L 0x00
#define POLCTRL_EN_ACT_H 0x00
#define PHACTRL_PHASE_MANUAL 0x01
#define DEFAULT_PHAD_QVGA (9)
#define DEFAULT_COMADJ (125)
/*
* This is only a psuedo I2C interface. We can't use the standard kernel
* routines as the interface is write only. We just assume the data is acked...
*/
static void lcdtg_ssp_i2c_send(u8 data)
{
corgi_ssp_lcdtg_send(POWERREG0_ADRS, data);
udelay(10);
}
static void lcdtg_i2c_send_bit(u8 data)
{
lcdtg_ssp_i2c_send(data);
lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK);
lcdtg_ssp_i2c_send(data);
}
static void lcdtg_i2c_send_start(u8 base)
{
lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
lcdtg_ssp_i2c_send(base);
}
static void lcdtg_i2c_send_stop(u8 base)
{
lcdtg_ssp_i2c_send(base);
lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK);
lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT);
}
static void lcdtg_i2c_send_byte(u8 base, u8 data)
{
int i;
for (i = 0; i < 8; i++) {
if (data & 0x80)
lcdtg_i2c_send_bit(base | POWER0_COM_DOUT);
else
lcdtg_i2c_send_bit(base);
data <<= 1;
}
}
static void lcdtg_i2c_wait_ack(u8 base)
{
lcdtg_i2c_send_bit(base);
}
static void lcdtg_set_common_voltage(u8 base_data, u8 data)
{
/* Set Common Voltage to M62332FP via I2C */
lcdtg_i2c_send_start(base_data);
lcdtg_i2c_send_byte(base_data, 0x9c);
lcdtg_i2c_wait_ack(base_data);
lcdtg_i2c_send_byte(base_data, 0x00);
lcdtg_i2c_wait_ack(base_data);
lcdtg_i2c_send_byte(base_data, data);
lcdtg_i2c_wait_ack(base_data);
lcdtg_i2c_send_stop(base_data);
}
/* Set Phase Adjust */
static void lcdtg_set_phadadj(int mode)
{
int adj;
switch(mode) {
case 480:
case 640:
/* Setting for VGA */
adj = sharpsl_param.phadadj;
if (adj < 0) {
adj = PHACTRL_PHASE_MANUAL;
} else {
adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL;
}
break;
case 240:
case 320:
default:
/* Setting for QVGA */
adj = (DEFAULT_PHAD_QVGA << 1) | PHACTRL_PHASE_MANUAL;
break;
}
corgi_ssp_lcdtg_send(PHACTRL_ADRS, adj);
}
static int lcd_inited;
void corgi_lcdtg_hw_init(int mode)
{
if (!lcd_inited) {
int comadj;
/* Initialize Internal Logic & Port */
corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE
| PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF);
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF
| POWER0_COM_OFF | POWER0_VCC5_OFF);
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
/* VDD(+8V), SVSS(-4V) ON */
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
mdelay(3);
/* DAC ON */
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
| POWER0_COM_OFF | POWER0_VCC5_OFF);
/* INIB = H, INI = L */
/* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */
corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF);
/* Set Common Voltage */
comadj = sharpsl_param.comadj;
if (comadj < 0)
comadj = DEFAULT_COMADJ;
lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj);
/* VCC5 ON, DAC ON */
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON |
POWER0_COM_OFF | POWER0_VCC5_ON);
/* GVSS(-8V) ON, VDD ON */
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
mdelay(2);
/* COM SIGNAL ON (PICTL[3] = L) */
corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIT_STATE);
/* COM ON, DAC ON, VCC5_ON */
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON
| POWER0_COM_ON | POWER0_VCC5_ON);
/* VW ON, GVSS ON, VDD ON */
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_ON | POWER1_GVSS_ON | POWER1_VDD_ON);
/* Signals output enable */
corgi_ssp_lcdtg_send(PICTRL_ADRS, 0);
/* Set Phase Adjust */
lcdtg_set_phadadj(mode);
/* Initialize for Input Signals from ATI */
corgi_ssp_lcdtg_send(POLCTRL_ADRS, POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE
| POLCTRL_DATA_POL_RISE | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H);
udelay(1000);
lcd_inited=1;
} else {
lcdtg_set_phadadj(mode);
}
switch(mode) {
case 480:
case 640:
/* Set Lcd Resolution (VGA) */
corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_VGA);
break;
case 240:
case 320:
default:
/* Set Lcd Resolution (QVGA) */
corgi_ssp_lcdtg_send(RESCTL_ADRS, RESCTL_QVGA);
break;
}
}
void corgi_lcdtg_suspend(void)
{
/* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */
mdelay(34);
/* (1)VW OFF */
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON);
/* (2)COM OFF */
corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF);
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON);
/* (3)Set Common Voltage Bias 0V */
lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0);
/* (4)GVSS OFF */
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON);
/* (5)VCC5 OFF */
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF);
/* (6)Set PDWN, INIOFF, DACOFF */
corgi_ssp_lcdtg_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF |
PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF);
/* (7)DAC OFF */
corgi_ssp_lcdtg_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF);
/* (8)VDD OFF */
corgi_ssp_lcdtg_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF);
lcd_inited = 0;
}

View file

@ -0,0 +1,276 @@
/*
* SSP control code for Sharp Corgi devices
*
* Copyright (c) 2004-2005 Richard Purdie
*
* 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/init.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <mach/hardware.h>
#include <asm/mach-types.h>
#include <mach/ssp.h>
#include <mach/pxa-regs.h>
#include <mach/pxa2xx-gpio.h>
#include <mach/regs-ssp.h>
#include "sharpsl.h"
static DEFINE_SPINLOCK(corgi_ssp_lock);
static struct ssp_dev corgi_ssp_dev;
static struct ssp_state corgi_ssp_state;
static struct corgissp_machinfo *ssp_machinfo;
/*
* There are three devices connected to the SSP interface:
* 1. A touchscreen controller (TI ADS7846 compatible)
* 2. An LCD controller (with some Backlight functionality)
* 3. A battery monitoring IC (Maxim MAX1111)
*
* Each device uses a different speed/mode of communication.
*
* The touchscreen is very sensitive and the most frequently used
* so the port is left configured for this.
*
* Devices are selected using Chip Selects on GPIOs.
*/
/*
* ADS7846 Routines
*/
unsigned long corgi_ssp_ads7846_putget(ulong data)
{
unsigned long flag;
u32 ret = 0;
spin_lock_irqsave(&corgi_ssp_lock, flag);
if (ssp_machinfo->cs_ads7846 >= 0)
GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
ssp_write_word(&corgi_ssp_dev,data);
ssp_read_word(&corgi_ssp_dev, &ret);
if (ssp_machinfo->cs_ads7846 >= 0)
GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
spin_unlock_irqrestore(&corgi_ssp_lock, flag);
return ret;
}
/*
* NOTE: These functions should always be called in interrupt context
* and use the _lock and _unlock functions. They are very time sensitive.
*/
void corgi_ssp_ads7846_lock(void)
{
spin_lock(&corgi_ssp_lock);
if (ssp_machinfo->cs_ads7846 >= 0)
GPCR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
}
void corgi_ssp_ads7846_unlock(void)
{
if (ssp_machinfo->cs_ads7846 >= 0)
GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846);
spin_unlock(&corgi_ssp_lock);
}
void corgi_ssp_ads7846_put(ulong data)
{
ssp_write_word(&corgi_ssp_dev,data);
}
unsigned long corgi_ssp_ads7846_get(void)
{
u32 ret = 0;
ssp_read_word(&corgi_ssp_dev, &ret);
return ret;
}
EXPORT_SYMBOL(corgi_ssp_ads7846_putget);
EXPORT_SYMBOL(corgi_ssp_ads7846_lock);
EXPORT_SYMBOL(corgi_ssp_ads7846_unlock);
EXPORT_SYMBOL(corgi_ssp_ads7846_put);
EXPORT_SYMBOL(corgi_ssp_ads7846_get);
/*
* LCD/Backlight Routines
*/
unsigned long corgi_ssp_dac_put(ulong data)
{
unsigned long flag, sscr1 = SSCR1_SPH;
u32 tmp;
spin_lock_irqsave(&corgi_ssp_lock, flag);
if (machine_is_spitz() || machine_is_akita() || machine_is_borzoi())
sscr1 = 0;
ssp_disable(&corgi_ssp_dev);
ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), sscr1, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_lcdcon));
ssp_enable(&corgi_ssp_dev);
if (ssp_machinfo->cs_lcdcon >= 0)
GPCR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
ssp_write_word(&corgi_ssp_dev,data);
/* Read null data back from device to prevent SSP overflow */
ssp_read_word(&corgi_ssp_dev, &tmp);
if (ssp_machinfo->cs_lcdcon >= 0)
GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon);
ssp_disable(&corgi_ssp_dev);
ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
ssp_enable(&corgi_ssp_dev);
spin_unlock_irqrestore(&corgi_ssp_lock, flag);
return 0;
}
void corgi_ssp_lcdtg_send(u8 adrs, u8 data)
{
corgi_ssp_dac_put(((adrs & 0x07) << 5) | (data & 0x1f));
}
void corgi_ssp_blduty_set(int duty)
{
corgi_ssp_lcdtg_send(0x02,duty);
}
EXPORT_SYMBOL(corgi_ssp_lcdtg_send);
EXPORT_SYMBOL(corgi_ssp_blduty_set);
/*
* Max1111 Routines
*/
int corgi_ssp_max1111_get(ulong data)
{
unsigned long flag;
long voltage = 0, voltage1 = 0, voltage2 = 0;
spin_lock_irqsave(&corgi_ssp_lock, flag);
if (ssp_machinfo->cs_max1111 >= 0)
GPCR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
ssp_disable(&corgi_ssp_dev);
ssp_config(&corgi_ssp_dev, (SSCR0_Motorola | (SSCR0_DSS & 0x07 )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_max1111));
ssp_enable(&corgi_ssp_dev);
udelay(1);
/* TB1/RB1 */
ssp_write_word(&corgi_ssp_dev,data);
ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1); /* null read */
/* TB12/RB2 */
ssp_write_word(&corgi_ssp_dev,0);
ssp_read_word(&corgi_ssp_dev, (u32*)&voltage1);
/* TB13/RB3*/
ssp_write_word(&corgi_ssp_dev,0);
ssp_read_word(&corgi_ssp_dev, (u32*)&voltage2);
ssp_disable(&corgi_ssp_dev);
ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
ssp_enable(&corgi_ssp_dev);
if (ssp_machinfo->cs_max1111 >= 0)
GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111);
spin_unlock_irqrestore(&corgi_ssp_lock, flag);
if (voltage1 & 0xc0 || voltage2 & 0x3f)
voltage = -1;
else
voltage = ((voltage1 << 2) & 0xfc) | ((voltage2 >> 6) & 0x03);
return voltage;
}
EXPORT_SYMBOL(corgi_ssp_max1111_get);
/*
* Support Routines
*/
void __init corgi_ssp_set_machinfo(struct corgissp_machinfo *machinfo)
{
ssp_machinfo = machinfo;
}
static int __init corgi_ssp_probe(struct platform_device *dev)
{
int ret;
/* Chip Select - Disable All */
if (ssp_machinfo->cs_lcdcon >= 0)
pxa_gpio_mode(ssp_machinfo->cs_lcdcon | GPIO_OUT | GPIO_DFLT_HIGH);
if (ssp_machinfo->cs_max1111 >= 0)
pxa_gpio_mode(ssp_machinfo->cs_max1111 | GPIO_OUT | GPIO_DFLT_HIGH);
if (ssp_machinfo->cs_ads7846 >= 0)
pxa_gpio_mode(ssp_machinfo->cs_ads7846 | GPIO_OUT | GPIO_DFLT_HIGH);
ret = ssp_init(&corgi_ssp_dev, ssp_machinfo->port, 0);
if (ret)
printk(KERN_ERR "Unable to register SSP handler!\n");
else {
ssp_disable(&corgi_ssp_dev);
ssp_config(&corgi_ssp_dev, (SSCR0_National | (SSCR0_DSS & 0x0b )), 0, 0, SSCR0_SerClkDiv(ssp_machinfo->clk_ads7846));
ssp_enable(&corgi_ssp_dev);
}
return ret;
}
static int corgi_ssp_remove(struct platform_device *dev)
{
ssp_exit(&corgi_ssp_dev);
return 0;
}
static int corgi_ssp_suspend(struct platform_device *dev, pm_message_t state)
{
ssp_flush(&corgi_ssp_dev);
ssp_save_state(&corgi_ssp_dev,&corgi_ssp_state);
return 0;
}
static int corgi_ssp_resume(struct platform_device *dev)
{
if (ssp_machinfo->cs_lcdcon >= 0)
GPSR(ssp_machinfo->cs_lcdcon) = GPIO_bit(ssp_machinfo->cs_lcdcon); /* High - Disable LCD Control/Timing Gen */
if (ssp_machinfo->cs_max1111 >= 0)
GPSR(ssp_machinfo->cs_max1111) = GPIO_bit(ssp_machinfo->cs_max1111); /* High - Disable MAX1111*/
if (ssp_machinfo->cs_ads7846 >= 0)
GPSR(ssp_machinfo->cs_ads7846) = GPIO_bit(ssp_machinfo->cs_ads7846); /* High - Disable ADS7846*/
ssp_restore_state(&corgi_ssp_dev,&corgi_ssp_state);
ssp_enable(&corgi_ssp_dev);
return 0;
}
static struct platform_driver corgissp_driver = {
.probe = corgi_ssp_probe,
.remove = corgi_ssp_remove,
.suspend = corgi_ssp_suspend,
.resume = corgi_ssp_resume,
.driver = {
.name = "corgi-ssp",
},
};
int __init corgi_ssp_init(void)
{
return platform_driver_register(&corgissp_driver);
}
arch_initcall(corgi_ssp_init);

View file

@ -113,6 +113,7 @@
* Shared data structures
*/
extern struct platform_device corgiscoop_device;
extern struct platform_device corgissp_device;
#endif /* __ASM_ARCH_CORGI_H */

View file

@ -9,7 +9,8 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __ASM_MACH_IRQS_H
#define __ASM_MACH_IRQS_H
#ifdef CONFIG_PXA_HAVE_ISA_IRQS
#define PXA_ISA_IRQ(x) (x)
@ -264,3 +265,5 @@
#endif
#endif /* CONFIG_PCI_HOST_ITE8152 */
#endif /* __ASM_MACH_IRQS_H */

View file

@ -142,7 +142,7 @@
#define SPITZ_SCP2_GPIO_BASE (NR_BUILTIN_GPIO + 12)
#define SPITZ_GPIO_IR_ON (SPITZ_SCP2_GPIO_BASE + 0)
#define SPITZ_GPIO_AKIN_PULLUP (SPITZ_SCP2_GPIO_BASE + 1
#define SPITZ_GPIO_AKIN_PULLUP (SPITZ_SCP2_GPIO_BASE + 1)
#define SPITZ_GPIO_RESERVED_1 (SPITZ_SCP2_GPIO_BASE + 2)
#define SPITZ_GPIO_RESERVED_2 (SPITZ_SCP2_GPIO_BASE + 3)
#define SPITZ_GPIO_RESERVED_3 (SPITZ_SCP2_GPIO_BASE + 4)
@ -187,4 +187,5 @@
*/
extern struct platform_device spitzscoop_device;
extern struct platform_device spitzscoop2_device;
extern struct platform_device spitzssp_device;
extern struct sharpsl_charger_machinfo spitz_pm_machinfo;

View file

@ -193,4 +193,7 @@
#define TOSA_KEY_MAIL KEY_MAIL
#endif
struct spi_device;
extern int tosa_bl_enable(struct spi_device *spi, int enable);
#endif /* _ASM_ARCH_TOSA_H_ */

View file

@ -60,7 +60,7 @@ int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
do_div(c, 1000000000);
period_cycles = c;
if (period_cycles < 0)
if (period_cycles < 1)
period_cycles = 1;
prescale = (period_cycles - 1) / 1024;
pv = period_cycles / (prescale + 1) - 1;

View file

@ -116,20 +116,33 @@ struct battery_thresh spitz_battery_levels_noac[] = {
{ 0, 0},
};
/* MAX1111 Commands */
#define MAXCTRL_PD0 1u << 0
#define MAXCTRL_PD1 1u << 1
#define MAXCTRL_SGL 1u << 2
#define MAXCTRL_UNI 1u << 3
#define MAXCTRL_SEL_SH 4
#define MAXCTRL_STR 1u << 7
/*
* Read MAX1111 ADC
*/
extern int max1111_read_channel(int);
int sharpsl_pm_pxa_read_max1111(int channel)
{
if (machine_is_tosa()) // Ugly, better move this function into another module
return 0;
#ifdef CONFIG_CORGI_SSP_DEPRECATED
return corgi_ssp_max1111_get((channel << MAXCTRL_SEL_SH) | MAXCTRL_PD0 | MAXCTRL_PD1
| MAXCTRL_SGL | MAXCTRL_UNI | MAXCTRL_STR);
#else
extern int max1111_read_channel(int);
/* max1111 accepts channels from 0-3, however,
* it is encoded from 0-7 here in the code.
*/
return max1111_read_channel(channel >> 1);
#endif
}
void sharpsl_pm_pxa_init(void)

View file

@ -31,6 +31,7 @@
#include <linux/gpio.h>
#include <linux/pda_power.h>
#include <linux/rfkill.h>
#include <linux/spi/spi.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
@ -42,6 +43,7 @@
#include <mach/mmc.h>
#include <mach/udc.h>
#include <mach/tosa_bt.h>
#include <mach/pxa2xx_spi.h>
#include <asm/mach/arch.h>
#include <mach/tosa.h>
@ -612,7 +614,7 @@ static int tosa_tc6393xb_enable(struct platform_device *dev)
rc = gpio_request(TOSA_GPIO_TC6393XB_SUSPEND, "tc6393xb #suspend");
if (rc)
goto err_req_suspend;
rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "l3v");
rc = gpio_request(TOSA_GPIO_TC6393XB_L3V_ON, "tc6393xb l3v");
if (rc)
goto err_req_l3v;
rc = gpio_direction_output(TOSA_GPIO_TC6393XB_L3V_ON, 0);
@ -772,6 +774,20 @@ static struct platform_device tosa_bt_device = {
.dev.platform_data = &tosa_bt_data,
};
static struct pxa2xx_spi_master pxa_ssp_master_info = {
.num_chipselect = 1,
};
static struct spi_board_info spi_board_info[] __initdata = {
{
.modalias = "tosa-lcd",
// .platform_data
.max_speed_hz = 28750,
.bus_num = 2,
.chip_select = 0,
.mode = SPI_MODE_0,
},
};
static struct platform_device *devices[] __initdata = {
&tosascoop_device,
@ -826,6 +842,9 @@ static void __init tosa_init(void)
pxa_set_i2c_info(NULL);
platform_scoop_config = &tosa_pcmcia_config;
pxa2xx_set_spi_info(2, &pxa_ssp_master_info);
spi_register_board_info(spi_board_info, ARRAY_SIZE(spi_board_info));
clk_add_alias("CLK_CK3P6MI", &tc6393xb_device.dev, "GPIO11_CLK", NULL);
platform_add_devices(devices, ARRAY_SIZE(devices));

View file

@ -399,7 +399,7 @@ static void trizeps4_irda_transceiver_mode(struct device *dev, int mode)
/* Switch mode */
if (mode & IR_SIRMODE)
trizeps_conxs_ircr &= ~ConXS_IRCR_MODE; /* Slow mode */
else if (mode & IR_FIRMODE) {
else if (mode & IR_FIRMODE)
trizeps_conxs_ircr |= ConXS_IRCR_MODE; /* Fast mode */
/* Switch power */

View file

@ -1033,8 +1033,7 @@ void __init s3c2443_init_clocks(int xtal)
fclk = pll / s3c2443_fclk_div(clkdiv0);
hclk = s3c2443_prediv_getrate(&clk_prediv);
hclk = hclk / s3c2443_get_hdiv(clkdiv0);
hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1);
hclk /= s3c2443_get_hdiv(clkdiv0);
pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);

View file

@ -400,9 +400,9 @@ config CPU_FEROCEON_OLD_ID
# ARMv6
config CPU_V6
bool "Support ARM V6 processor"
depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM7X00A || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
depends on ARCH_INTEGRATOR || MACH_REALVIEW_EB || ARCH_OMAP2 || ARCH_MX3 || ARCH_MSM || MACH_REALVIEW_PB11MP || MACH_REALVIEW_PB1176
default y if ARCH_MX3
default y if ARCH_MSM7X00A
default y if ARCH_MSM
select CPU_32v6
select CPU_ABRT_EV6
select CPU_PABRT_NOIFAR

View file

@ -29,7 +29,7 @@ ENTRY(v4_flush_user_cache_all)
* Clean and invalidate the entire cache.
*/
ENTRY(v4_flush_kern_cache_all)
#ifdef CPU_CP15
#ifdef CONFIG_CPU_CP15
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 @ flush ID cache
mov pc, lr
@ -48,7 +48,7 @@ ENTRY(v4_flush_kern_cache_all)
* - flags - vma_area_struct flags describing address space
*/
ENTRY(v4_flush_user_cache_range)
#ifdef CPU_CP15
#ifdef CONFIG_CPU_CP15
mov ip, #0
mcreq p15, 0, ip, c7, c7, 0 @ flush ID cache
mov pc, lr
@ -116,7 +116,7 @@ ENTRY(v4_dma_inv_range)
* - end - virtual end address
*/
ENTRY(v4_dma_flush_range)
#ifdef CPU_CP15
#ifdef CONFIG_CPU_CP15
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 @ flush ID cache
#endif

View file

@ -180,8 +180,8 @@ __v7_setup:
mov r10, #0x1f @ domains 0, 1 = manager
mcr p15, 0, r10, c3, c0, 0 @ load domain access register
#endif
ldr r5, =0x40e040e0
ldr r6, =0xff0aa1a8
ldr r5, =0xff0aa1a8
ldr r6, =0x40e040e0
mcr p15, 0, r5, c10, c2, 0 @ write PRRR
mcr p15, 0, r6, c10, c2, 1 @ write NMRR
adr r5, v7_crval

View file

@ -315,7 +315,7 @@ static int clk_pwm_tin_set_parent(struct clk *clk, struct clk *parent)
if (parent == s3c24xx_pwmclk_tclk(id))
bits = S3C2410_TCFG1_MUX_TCLK << shift;
else if (parent == s3c24xx_pwmclk_tdiv(id))
bits = clk_pwm_tdiv_bits(to_tdiv(clk)) << shift;
bits = clk_pwm_tdiv_bits(to_tdiv(parent)) << shift;
else
return -EINVAL;

View file

@ -56,7 +56,7 @@ static struct clk *clk_scaler[2];
} \
}
#define DEFINE_TIMER(_tmr_no, _irq) \
#define DEFINE_S3C_TIMER(_tmr_no, _irq) \
.name = "s3c24xx-pwm", \
.id = _tmr_no, \
.num_resources = TIMER_RESOURCE_SIZE, \
@ -67,11 +67,11 @@ static struct clk *clk_scaler[2];
*/
struct platform_device s3c_device_timer[] = {
[0] = { DEFINE_TIMER(0, IRQ_TIMER0) },
[1] = { DEFINE_TIMER(1, IRQ_TIMER1) },
[2] = { DEFINE_TIMER(2, IRQ_TIMER2) },
[3] = { DEFINE_TIMER(3, IRQ_TIMER3) },
[4] = { DEFINE_TIMER(4, IRQ_TIMER4) },
[0] = { DEFINE_S3C_TIMER(0, IRQ_TIMER0) },
[1] = { DEFINE_S3C_TIMER(1, IRQ_TIMER1) },
[2] = { DEFINE_S3C_TIMER(2, IRQ_TIMER2) },
[3] = { DEFINE_S3C_TIMER(3, IRQ_TIMER3) },
[4] = { DEFINE_S3C_TIMER(4, IRQ_TIMER4) },
};
static inline int pwm_is_tdiv(struct pwm_device *pwm)

View file

@ -121,11 +121,19 @@ config BOARD_ATSTK1000
config BOARD_ATNGW100
bool "ATNGW100 Network Gateway"
select CPU_AT32AP7000
config BOARD_FAVR_32
bool "Favr-32 LCD-board"
select CPU_AT32AP7000
config BOARD_MIMC200
bool "MIMC200 CPU board"
select CPU_AT32AP7000
endchoice
if BOARD_ATSTK1000
source "arch/avr32/boards/atstk1000/Kconfig"
endif
source "arch/avr32/boards/atngw100/Kconfig"
source "arch/avr32/boards/favr-32/Kconfig"
choice
prompt "Boot loader type"

View file

@ -33,6 +33,8 @@ head-y += arch/avr32/kernel/head.o
core-y += $(machdirs)
core-$(CONFIG_BOARD_ATSTK1000) += arch/avr32/boards/atstk1000/
core-$(CONFIG_BOARD_ATNGW100) += arch/avr32/boards/atngw100/
core-$(CONFIG_BOARD_FAVR_32) += arch/avr32/boards/favr-32/
core-$(CONFIG_BOARD_MIMC200) += arch/avr32/boards/mimc200/
core-$(CONFIG_LOADER_U_BOOT) += arch/avr32/boot/u-boot/
core-y += arch/avr32/kernel/
core-y += arch/avr32/mm/

View file

@ -0,0 +1,35 @@
# NGW100 customization
if BOARD_ATNGW100
config BOARD_ATNGW100_EVKLCD10X
bool "Add support for EVKLCD10X addon board"
help
This enables support for the EVKLCD100 (QVGA) or EVKLCD101 (VGA)
addon board for the NGW100. By enabling this the LCD controller and
AC97 controller is added as platform devices.
This choice disables the detect pin and the write-protect pin for the
MCI platform device, since it conflicts with the LCD platform device.
The MCI pins can be reenabled by editing the "add device function" but
this may break the setup for other displays that use these pins.
Choose 'Y' here if you have a EVKLCD100/101 connected to the NGW100.
choice
prompt "LCD panel resolution on EVKLCD10X"
depends on BOARD_ATNGW100_EVKLCD10X
default BOARD_ATNGW100_EVKLCD10X_VGA
config BOARD_ATNGW100_EVKLCD10X_QVGA
bool "QVGA (320x240)"
config BOARD_ATNGW100_EVKLCD10X_VGA
bool "VGA (640x480)"
config BOARD_ATNGW100_EVKLCD10X_POW_QVGA
bool "Powertip QVGA (320x240)"
endchoice
endif # BOARD_ATNGW100

View file

@ -1 +1,2 @@
obj-y += setup.o flash.o
obj-y += setup.o flash.o
obj-$(CONFIG_BOARD_ATNGW100_EVKLCD10X) += evklcd10x.o

View file

@ -0,0 +1,155 @@
/*
* Board-specific setup code for the ATEVKLCD10X addon board to the ATNGW100
* Network Gateway
*
* Copyright (C) 2008 Atmel 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/init.h>
#include <linux/linkage.h>
#include <linux/fb.h>
#include <linux/platform_device.h>
#include <video/atmel_lcdc.h>
#include <asm/setup.h>
#include <mach/at32ap700x.h>
#include <mach/board.h>
static struct ac97c_platform_data __initdata ac97c0_data = {
.dma_rx_periph_id = 3,
.dma_tx_periph_id = 4,
.dma_controller_id = 0,
.reset_pin = GPIO_PIN_PB(19),
};
#ifdef CONFIG_BOARD_ATNGW100_EVKLCD10X_VGA
static struct fb_videomode __initdata tcg057vglad_modes[] = {
{
.name = "640x480 @ 60",
.refresh = 60,
.xres = 640, .yres = 480,
.pixclock = KHZ2PICOS(25180),
.left_margin = 64, .right_margin = 31,
.upper_margin = 34, .lower_margin = 2,
.hsync_len = 96, .vsync_len = 4,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
};
static struct fb_monspecs __initdata atevklcd10x_default_monspecs = {
.manufacturer = "KYO",
.monitor = "TCG057VGLAD",
.modedb = tcg057vglad_modes,
.modedb_len = ARRAY_SIZE(tcg057vglad_modes),
.hfmin = 19948,
.hfmax = 31478,
.vfmin = 50,
.vfmax = 67,
.dclkmax = 28330000,
};
static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
.default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_MEMOR_BIG),
.default_monspecs = &atevklcd10x_default_monspecs,
.guard_time = 2,
};
#elif CONFIG_BOARD_ATNGW100_EVKLCD10X_QVGA
static struct fb_videomode __initdata tcg057qvlad_modes[] = {
{
.name = "320x240 @ 60",
.refresh = 60,
.xres = 320, .yres = 240,
.pixclock = KHZ2PICOS(6300),
.left_margin = 52, .right_margin = 28,
.upper_margin = 7, .lower_margin = 2,
.hsync_len = 96, .vsync_len = 4,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
};
static struct fb_monspecs __initdata atevklcd10x_default_monspecs = {
.manufacturer = "KYO",
.monitor = "TCG057QVLAD",
.modedb = tcg057qvlad_modes,
.modedb_len = ARRAY_SIZE(tcg057qvlad_modes),
.hfmin = 19948,
.hfmax = 31478,
.vfmin = 50,
.vfmax = 67,
.dclkmax = 7000000,
};
static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
.default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_MEMOR_BIG),
.default_monspecs = &atevklcd10x_default_monspecs,
.guard_time = 2,
};
#elif CONFIG_BOARD_ATNGW100_EVKLCD10X_POW_QVGA
static struct fb_videomode __initdata ph320240t_modes[] = {
{
.name = "320x240 @ 60",
.refresh = 60,
.xres = 320, .yres = 240,
.pixclock = KHZ2PICOS(6300),
.left_margin = 38, .right_margin = 20,
.upper_margin = 15, .lower_margin = 5,
.hsync_len = 30, .vsync_len = 3,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
};
static struct fb_monspecs __initdata atevklcd10x_default_monspecs = {
.manufacturer = "POW",
.monitor = "PH320240T",
.modedb = ph320240t_modes,
.modedb_len = ARRAY_SIZE(ph320240t_modes),
.hfmin = 14400,
.hfmax = 21600,
.vfmin = 50,
.vfmax = 90,
.dclkmax = 6400000,
};
static struct atmel_lcdfb_info __initdata atevklcd10x_lcdc_data = {
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
.default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_MEMOR_BIG),
.default_monspecs = &atevklcd10x_default_monspecs,
.guard_time = 2,
};
#endif
static int __init atevklcd10x_init(void)
{
at32_add_device_ac97c(0, &ac97c0_data);
at32_add_device_lcdc(0, &atevklcd10x_lcdc_data,
fbmem_start, fbmem_size, 1);
return 0;
}
postcore_initcall(atevklcd10x_init);

View file

@ -56,8 +56,13 @@ static struct spi_board_info spi0_board_info[] __initdata = {
static struct mci_platform_data __initdata mci0_data = {
.slot[0] = {
.bus_width = 4,
#ifndef CONFIG_BOARD_ATNGW100_EVKLCD10X
.detect_pin = GPIO_PIN_PC(25),
.wp_pin = GPIO_PIN_PE(0),
#else
.detect_pin = GPIO_PIN_NONE,
.wp_pin = GPIO_PIN_NONE,
#endif
},
};
@ -172,8 +177,6 @@ static int __init atngw100_init(void)
* reserve any pins for it.
*/
at32_add_system_devices();
at32_add_device_usart(0);
set_hw_addr(at32_add_device_eth(0, &eth_data[0]));

View file

@ -305,8 +305,6 @@ static int __init atstk1002_init(void)
at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */
at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */
at32_add_system_devices();
#ifdef CONFIG_BOARD_ATSTK1006
smc_set_timing(&nand_config, &nand_timing);
smc_set_configuration(3, &nand_config);

View file

@ -149,8 +149,6 @@ static int __init atstk1003_init(void)
at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */
at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */
at32_add_system_devices();
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
at32_add_device_usart(1);
#else

View file

@ -132,8 +132,6 @@ void __init setup_board(void)
static int __init atstk1004_init(void)
{
at32_add_system_devices();
#ifdef CONFIG_BOARD_ATSTK100X_SW2_CUSTOM
at32_add_device_usart(1);
#else

View file

@ -0,0 +1,22 @@
# Favr-32 customization
if BOARD_FAVR_32
config BOARD_FAVR32_ABDAC_RATE
int "DAC target rate"
default 44100
range 32000 50000
help
Specify the target rate the internal DAC should try to match. This
will use PLL1 to generate a frequency as close as possible to this
rate.
Must be within the range 32000 to 50000, which should be suitable to
generate most other frequencies in power of 2 steps.
Ex:
48000 will also suit 24000 and 12000
44100 will also suit 22050 and 11025
32000 will also suit 16000 and 8000
endif # BOARD_FAVR_32

View file

@ -0,0 +1 @@
obj-y += setup.o flash.o

View file

@ -0,0 +1,98 @@
/*
* Favr-32 board-specific flash initialization
*
* Copyright (C) 2008 Atmel 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/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <asm/arch/smc.h>
static struct smc_timing flash_timing __initdata = {
.ncs_read_setup = 0,
.nrd_setup = 40,
.ncs_write_setup = 0,
.nwe_setup = 10,
.ncs_read_pulse = 80,
.nrd_pulse = 40,
.ncs_write_pulse = 65,
.nwe_pulse = 55,
.read_cycle = 120,
.write_cycle = 120,
};
static struct smc_config flash_config __initdata = {
.bus_width = 2,
.nrd_controlled = 1,
.nwe_controlled = 1,
.byte_write = 1,
};
static struct mtd_partition flash_parts[] = {
{
.name = "u-boot",
.offset = 0x00000000,
.size = 0x00020000, /* 128 KiB */
.mask_flags = MTD_WRITEABLE,
},
{
.name = "root",
.offset = 0x00020000,
.size = 0x007d0000,
},
{
.name = "env",
.offset = 0x007f0000,
.size = 0x00010000,
.mask_flags = MTD_WRITEABLE,
},
};
static struct physmap_flash_data flash_data = {
.width = 2,
.nr_parts = ARRAY_SIZE(flash_parts),
.parts = flash_parts,
};
static struct resource flash_resource = {
.start = 0x00000000,
.end = 0x007fffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device flash_device = {
.name = "physmap-flash",
.id = 0,
.resource = &flash_resource,
.num_resources = 1,
.dev = {
.platform_data = &flash_data,
},
};
/* This needs to be called after the SMC has been initialized */
static int __init favr32_flash_init(void)
{
int ret;
smc_set_timing(&flash_config, &flash_timing);
ret = smc_set_configuration(0, &flash_config);
if (ret < 0) {
printk(KERN_ERR "Favr-32: failed to set NOR flash timing\n");
return ret;
}
platform_device_register(&flash_device);
return 0;
}
device_initcall(favr32_flash_init);

View file

@ -0,0 +1,352 @@
/*
* Favr-32 board-specific setup code.
*
* Copyright (C) 2008 Atmel 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/clk.h>
#include <linux/etherdevice.h>
#include <linux/bootmem.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/types.h>
#include <linux/linkage.h>
#include <linux/gpio.h>
#include <linux/leds.h>
#include <linux/atmel-pwm-bl.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <video/atmel_lcdc.h>
#include <asm/setup.h>
#include <asm/arch/at32ap700x.h>
#include <asm/arch/init.h>
#include <asm/arch/board.h>
#include <asm/arch/portmux.h>
/* Oscillator frequencies. These are board-specific */
unsigned long at32_board_osc_rates[3] = {
[0] = 32768, /* 32.768 kHz on RTC osc */
[1] = 20000000, /* 20 MHz on osc0 */
[2] = 12000000, /* 12 MHz on osc1 */
};
/* Initialized by bootloader-specific startup code. */
struct tag *bootloader_tags __initdata;
struct eth_addr {
u8 addr[6];
};
static struct eth_addr __initdata hw_addr[1];
static struct eth_platform_data __initdata eth_data[1] = {
{
.phy_mask = ~(1U << 1),
},
};
static int ads7843_get_pendown_state(void)
{
return !gpio_get_value(GPIO_PIN_PB(3));
}
static struct ads7846_platform_data ads7843_data = {
.model = 7843,
.get_pendown_state = ads7843_get_pendown_state,
.pressure_max = 255,
/*
* Values below are for debounce filtering, these can be experimented
* with further.
*/
.debounce_max = 20,
.debounce_rep = 4,
.debounce_tol = 5,
};
static struct spi_board_info __initdata spi1_board_info[] = {
{
/* ADS7843 touch controller */
.modalias = "ads7846",
.max_speed_hz = 2000000,
.chip_select = 0,
.bus_num = 1,
.platform_data = &ads7843_data,
},
};
static struct fb_videomode __initdata lb104v03_modes[] = {
{
.name = "640x480 @ 50",
.refresh = 50,
.xres = 640, .yres = 480,
.pixclock = KHZ2PICOS(25100),
.left_margin = 90, .right_margin = 70,
.upper_margin = 30, .lower_margin = 15,
.hsync_len = 12, .vsync_len = 2,
.sync = 0,
.vmode = FB_VMODE_NONINTERLACED,
},
};
static struct fb_monspecs __initdata favr32_default_monspecs = {
.manufacturer = "LG",
.monitor = "LB104V03",
.modedb = lb104v03_modes,
.modedb_len = ARRAY_SIZE(lb104v03_modes),
.hfmin = 27273,
.hfmax = 31111,
.vfmin = 45,
.vfmax = 60,
.dclkmax = 28000000,
};
struct atmel_lcdfb_info __initdata favr32_lcdc_data = {
.default_bpp = 16,
.default_dmacon = ATMEL_LCDC_DMAEN | ATMEL_LCDC_DMA2DEN,
.default_lcdcon2 = (ATMEL_LCDC_DISTYPE_TFT
| ATMEL_LCDC_CLKMOD_ALWAYSACTIVE
| ATMEL_LCDC_MEMOR_BIG),
.default_monspecs = &favr32_default_monspecs,
.guard_time = 2,
};
static struct gpio_led favr32_leds[] = {
{
.name = "green",
.gpio = GPIO_PIN_PE(19),
.default_trigger = "heartbeat",
.active_low = 1,
},
{
.name = "red",
.gpio = GPIO_PIN_PE(20),
.active_low = 1,
},
};
static struct gpio_led_platform_data favr32_led_data = {
.num_leds = ARRAY_SIZE(favr32_leds),
.leds = favr32_leds,
};
static struct platform_device favr32_led_dev = {
.name = "leds-gpio",
.id = 0,
.dev = {
.platform_data = &favr32_led_data,
},
};
/*
* The next two functions should go away as the boot loader is
* supposed to initialize the macb address registers with a valid
* ethernet address. But we need to keep it around for a while until
* we can be reasonably sure the boot loader does this.
*
* The phy_id is ignored as the driver will probe for it.
*/
static int __init parse_tag_ethernet(struct tag *tag)
{
int i;
i = tag->u.ethernet.mac_index;
if (i < ARRAY_SIZE(hw_addr))
memcpy(hw_addr[i].addr, tag->u.ethernet.hw_address,
sizeof(hw_addr[i].addr));
return 0;
}
__tagtable(ATAG_ETHERNET, parse_tag_ethernet);
static void __init set_hw_addr(struct platform_device *pdev)
{
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
const u8 *addr;
void __iomem *regs;
struct clk *pclk;
if (!res)
return;
if (pdev->id >= ARRAY_SIZE(hw_addr))
return;
addr = hw_addr[pdev->id].addr;
if (!is_valid_ether_addr(addr))
return;
/*
* Since this is board-specific code, we'll cheat and use the
* physical address directly as we happen to know that it's
* the same as the virtual address.
*/
regs = (void __iomem __force *)res->start;
pclk = clk_get(&pdev->dev, "pclk");
if (!pclk)
return;
clk_enable(pclk);
__raw_writel((addr[3] << 24) | (addr[2] << 16)
| (addr[1] << 8) | addr[0], regs + 0x98);
__raw_writel((addr[5] << 8) | addr[4], regs + 0x9c);
clk_disable(pclk);
clk_put(pclk);
}
void __init favr32_setup_leds(void)
{
unsigned i;
for (i = 0; i < ARRAY_SIZE(favr32_leds); i++)
at32_select_gpio(favr32_leds[i].gpio, AT32_GPIOF_OUTPUT);
platform_device_register(&favr32_led_dev);
}
static struct atmel_pwm_bl_platform_data atmel_pwm_bl_pdata = {
.pwm_channel = 2,
.pwm_frequency = 200000,
.pwm_compare_max = 345,
.pwm_duty_max = 345,
.pwm_duty_min = 90,
.pwm_active_low = 1,
.gpio_on = GPIO_PIN_PA(28),
.on_active_low = 0,
};
static struct platform_device atmel_pwm_bl_dev = {
.name = "atmel-pwm-bl",
.id = 0,
.dev = {
.platform_data = &atmel_pwm_bl_pdata,
},
};
static void __init favr32_setup_atmel_pwm_bl(void)
{
platform_device_register(&atmel_pwm_bl_dev);
at32_select_gpio(atmel_pwm_bl_pdata.gpio_on, 0);
}
void __init setup_board(void)
{
at32_map_usart(3, 0); /* USART 3 => /dev/ttyS0 */
at32_setup_serial_console(0);
}
static int __init set_abdac_rate(struct platform_device *pdev)
{
int retval;
struct clk *osc1;
struct clk *pll1;
struct clk *abdac;
if (pdev == NULL)
return -ENXIO;
osc1 = clk_get(NULL, "osc1");
if (IS_ERR(osc1)) {
retval = PTR_ERR(osc1);
goto out;
}
pll1 = clk_get(NULL, "pll1");
if (IS_ERR(pll1)) {
retval = PTR_ERR(pll1);
goto out_osc1;
}
abdac = clk_get(&pdev->dev, "sample_clk");
if (IS_ERR(abdac)) {
retval = PTR_ERR(abdac);
goto out_pll1;
}
retval = clk_set_parent(pll1, osc1);
if (retval != 0)
goto out_abdac;
/*
* Rate is 32000 to 50000 and ABDAC oversamples 256x. Multiply, in
* power of 2, to a value above 80 MHz. Power of 2 so it is possible
* for the generic clock to divide it down again and 80 MHz is the
* lowest frequency for the PLL.
*/
retval = clk_round_rate(pll1,
CONFIG_BOARD_FAVR32_ABDAC_RATE * 256 * 16);
if (retval < 0)
goto out_abdac;
retval = clk_set_rate(pll1, retval);
if (retval != 0)
goto out_abdac;
retval = clk_set_parent(abdac, pll1);
if (retval != 0)
goto out_abdac;
out_abdac:
clk_put(abdac);
out_pll1:
clk_put(pll1);
out_osc1:
clk_put(osc1);
out:
return retval;
}
static int __init favr32_init(void)
{
/*
* Favr-32 uses 32-bit SDRAM interface. Reserve the SDRAM-specific
* pins so that nobody messes with them.
*/
at32_reserve_pin(GPIO_PIN_PE(0)); /* DATA[16] */
at32_reserve_pin(GPIO_PIN_PE(1)); /* DATA[17] */
at32_reserve_pin(GPIO_PIN_PE(2)); /* DATA[18] */
at32_reserve_pin(GPIO_PIN_PE(3)); /* DATA[19] */
at32_reserve_pin(GPIO_PIN_PE(4)); /* DATA[20] */
at32_reserve_pin(GPIO_PIN_PE(5)); /* DATA[21] */
at32_reserve_pin(GPIO_PIN_PE(6)); /* DATA[22] */
at32_reserve_pin(GPIO_PIN_PE(7)); /* DATA[23] */
at32_reserve_pin(GPIO_PIN_PE(8)); /* DATA[24] */
at32_reserve_pin(GPIO_PIN_PE(9)); /* DATA[25] */
at32_reserve_pin(GPIO_PIN_PE(10)); /* DATA[26] */
at32_reserve_pin(GPIO_PIN_PE(11)); /* DATA[27] */
at32_reserve_pin(GPIO_PIN_PE(12)); /* DATA[28] */
at32_reserve_pin(GPIO_PIN_PE(13)); /* DATA[29] */
at32_reserve_pin(GPIO_PIN_PE(14)); /* DATA[30] */
at32_reserve_pin(GPIO_PIN_PE(15)); /* DATA[31] */
at32_reserve_pin(GPIO_PIN_PE(26)); /* SDCS */
at32_select_gpio(GPIO_PIN_PB(3), 0); /* IRQ from ADS7843 */
at32_add_system_devices();
at32_add_device_usart(0);
set_hw_addr(at32_add_device_eth(0, &eth_data[0]));
spi1_board_info[0].irq = gpio_to_irq(GPIO_PIN_PB(3));
set_abdac_rate(at32_add_device_abdac(0));
at32_add_device_pwm(1 << atmel_pwm_bl_pdata.pwm_channel);
at32_add_device_spi(1, spi1_board_info, ARRAY_SIZE(spi1_board_info));
at32_add_device_mci(0, NULL);
at32_add_device_usba(0, NULL);
at32_add_device_lcdc(0, &favr32_lcdc_data, fbmem_start, fbmem_size, 0);
favr32_setup_leds();
favr32_setup_atmel_pwm_bl();
return 0;
}
postcore_initcall(favr32_init);

View file

@ -0,0 +1 @@
obj-y += setup.o flash.o fram.o

View file

@ -0,0 +1,143 @@
/*
* MIMC200 board-specific flash initialization
*
* Copyright (C) 2008 Mercury IMC Ltd
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
#include <mach/smc.h>
static struct smc_timing flash_timing __initdata = {
.ncs_read_setup = 0,
.nrd_setup = 15,
.ncs_write_setup = 0,
.nwe_setup = 0,
.ncs_read_pulse = 115,
.nrd_pulse = 110,
.ncs_write_pulse = 60,
.nwe_pulse = 60,
.read_cycle = 115,
.write_cycle = 100,
};
static struct smc_config flash_config __initdata = {
.bus_width = 2,
.nrd_controlled = 1,
.nwe_controlled = 1,
.byte_write = 1,
};
/* system flash definition */
static struct mtd_partition flash_parts_system[] = {
{
.name = "u-boot",
.offset = 0x00000000,
.size = 0x00020000, /* 128 KiB */
.mask_flags = MTD_WRITEABLE,
},
{
.name = "root",
.offset = 0x00020000,
.size = 0x007c0000,
},
{
.name = "splash",
.offset = 0x007e0000,
.size = 0x00010000, /* 64KiB */
},
{
.name = "env",
.offset = 0x007f0000,
.size = 0x00010000,
.mask_flags = MTD_WRITEABLE,
},
};
static struct physmap_flash_data flash_system = {
.width = 2,
.nr_parts = ARRAY_SIZE(flash_parts_system),
.parts = flash_parts_system,
};
static struct resource flash_resource_system = {
.start = 0x00000000,
.end = 0x007fffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device flash_device_system = {
.name = "physmap-flash",
.id = 0,
.resource = &flash_resource_system,
.num_resources = 1,
.dev = {
.platform_data = &flash_system,
},
};
/* data flash definition */
static struct mtd_partition flash_parts_data[] = {
{
.name = "data",
.offset = 0x00000000,
.size = 0x00800000,
},
};
static struct physmap_flash_data flash_data = {
.width = 2,
.nr_parts = ARRAY_SIZE(flash_parts_data),
.parts = flash_parts_data,
};
static struct resource flash_resource_data = {
.start = 0x08000000,
.end = 0x087fffff,
.flags = IORESOURCE_MEM,
};
static struct platform_device flash_device_data = {
.name = "physmap-flash",
.id = 1,
.resource = &flash_resource_data,
.num_resources = 1,
.dev = {
.platform_data = &flash_data,
},
};
/* This needs to be called after the SMC has been initialized */
static int __init mimc200_flash_init(void)
{
int ret;
smc_set_timing(&flash_config, &flash_timing);
ret = smc_set_configuration(0, &flash_config);
if (ret < 0) {
printk(KERN_ERR "mimc200: failed to set 'System' NOR flash timing\n");
return ret;
}
ret = smc_set_configuration(1, &flash_config);
if (ret < 0) {
printk(KERN_ERR "mimc200: failed to set 'Data' NOR flash timing\n");
return ret;
}
platform_device_register(&flash_device_system);
platform_device_register(&flash_device_data);
return 0;
}
device_initcall(mimc200_flash_init);

Some files were not shown because too many files have changed in this diff Show more