Commit 59f91e5d authored by Jiri Kosina's avatar Jiri Kosina

Merge branch 'master' into for-next

Conflicts:
	include/linux/mmzone.h

Synced with Linus' tree so that trivial patch can be applied
on top of up-to-date code properly.
Reported-by: default avatarStephen Rothwell <sfr@canb.auug.org.au>
parents 57bdfdd8 89abfab1
What: /sys/bus/i2c/devices/.../output_hvled[n]
Date: April 2012
KernelVersion: 3.5
Contact: Johan Hovold <jhovold@gmail.com>
Description:
Set the controlling backlight device for high-voltage current
sink HVLED[n] (n = 1, 2) (0, 1).
What: /sys/bus/i2c/devices/.../output_lvled[n]
Date: April 2012
KernelVersion: 3.5
Contact: Johan Hovold <jhovold@gmail.com>
Description:
Set the controlling led device for low-voltage current sink
LVLED[n] (n = 1..5) (0..3).
...@@ -184,12 +184,14 @@ behind this approach is that a cgroup that aggressively uses a shared ...@@ -184,12 +184,14 @@ behind this approach is that a cgroup that aggressively uses a shared
page will eventually get charged for it (once it is uncharged from page will eventually get charged for it (once it is uncharged from
the cgroup that brought it in -- this will happen on memory pressure). the cgroup that brought it in -- this will happen on memory pressure).
But see section 8.2: when moving a task to another cgroup, its pages may
be recharged to the new cgroup, if move_charge_at_immigrate has been chosen.
Exception: If CONFIG_CGROUP_CGROUP_MEM_RES_CTLR_SWAP is not used. Exception: If CONFIG_CGROUP_CGROUP_MEM_RES_CTLR_SWAP is not used.
When you do swapoff and make swapped-out pages of shmem(tmpfs) to When you do swapoff and make swapped-out pages of shmem(tmpfs) to
be backed into memory in force, charges for pages are accounted against the be backed into memory in force, charges for pages are accounted against the
caller of swapoff rather than the users of shmem. caller of swapoff rather than the users of shmem.
2.4 Swap Extension (CONFIG_CGROUP_MEM_RES_CTLR_SWAP) 2.4 Swap Extension (CONFIG_CGROUP_MEM_RES_CTLR_SWAP)
Swap Extension allows you to record charge for swap. A swapped-in page is Swap Extension allows you to record charge for swap. A swapped-in page is
...@@ -430,17 +432,10 @@ hierarchical_memory_limit - # of bytes of memory limit with regard to hierarchy ...@@ -430,17 +432,10 @@ hierarchical_memory_limit - # of bytes of memory limit with regard to hierarchy
hierarchical_memsw_limit - # of bytes of memory+swap limit with regard to hierarchical_memsw_limit - # of bytes of memory+swap limit with regard to
hierarchy under which memory cgroup is. hierarchy under which memory cgroup is.
total_cache - sum of all children's "cache" total_<counter> - # hierarchical version of <counter>, which in
total_rss - sum of all children's "rss" addition to the cgroup's own value includes the
total_mapped_file - sum of all children's "cache" sum of all hierarchical children's values of
total_pgpgin - sum of all children's "pgpgin" <counter>, i.e. total_cache
total_pgpgout - sum of all children's "pgpgout"
total_swap - sum of all children's "swap"
total_inactive_anon - sum of all children's "inactive_anon"
total_active_anon - sum of all children's "active_anon"
total_inactive_file - sum of all children's "inactive_file"
total_active_file - sum of all children's "active_file"
total_unevictable - sum of all children's "unevictable"
# The following additional stats are dependent on CONFIG_DEBUG_VM. # The following additional stats are dependent on CONFIG_DEBUG_VM.
...@@ -622,8 +617,7 @@ memory cgroup. ...@@ -622,8 +617,7 @@ memory cgroup.
bit | what type of charges would be moved ? bit | what type of charges would be moved ?
-----+------------------------------------------------------------------------ -----+------------------------------------------------------------------------
0 | A charge of an anonymous page(or swap of it) used by the target task. 0 | A charge of an anonymous page(or swap of it) used by the target task.
| Those pages and swaps must be used only by the target task. You must | You must enable Swap Extension(see 2.4) to enable move of swap charges.
| enable Swap Extension(see 2.4) to enable move of swap charges.
-----+------------------------------------------------------------------------ -----+------------------------------------------------------------------------
1 | A charge of file pages(normal file, tmpfs file(e.g. ipc shared memory) 1 | A charge of file pages(normal file, tmpfs file(e.g. ipc shared memory)
| and swaps of tmpfs file) mmapped by the target task. Unlike the case of | and swaps of tmpfs file) mmapped by the target task. Unlike the case of
...@@ -636,8 +630,6 @@ memory cgroup. ...@@ -636,8 +630,6 @@ memory cgroup.
8.3 TODO 8.3 TODO
- Implement madvise(2) to let users decide the vma to be moved or not to be
moved.
- All of moving charge operations are done under cgroup_mutex. It's not good - All of moving charge operations are done under cgroup_mutex. It's not good
behavior to hold the mutex too long, so we may need some trick. behavior to hold the mutex too long, so we may need some trick.
......
* Dialog DA9052/53 Power Management Integrated Circuit (PMIC)
Required properties:
- compatible : Should be "dlg,da9052", "dlg,da9053-aa",
"dlg,da9053-ab", or "dlg,da9053-bb"
Sub-nodes:
- regulators : Contain the regulator nodes. The DA9052/53 regulators are
bound using their names as listed below:
buck0 : regulator BUCK0
buck1 : regulator BUCK1
buck2 : regulator BUCK2
buck3 : regulator BUCK3
ldo4 : regulator LDO4
ldo5 : regulator LDO5
ldo6 : regulator LDO6
ldo7 : regulator LDO7
ldo8 : regulator LDO8
ldo9 : regulator LDO9
ldo10 : regulator LDO10
ldo11 : regulator LDO11
ldo12 : regulator LDO12
ldo13 : regulator LDO13
The bindings details of individual regulator device can be found in:
Documentation/devicetree/bindings/regulator/regulator.txt
Examples:
i2c@63fc8000 { /* I2C1 */
status = "okay";
pmic: dialog@48 {
compatible = "dlg,da9053-aa";
reg = <0x48>;
regulators {
buck0 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2075000>;
};
buck1 {
regulator-min-microvolt = <500000>;
regulator-max-microvolt = <2075000>;
};
buck2 {
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <2500000>;
};
buck3 {
regulator-min-microvolt = <925000>;
regulator-max-microvolt = <2500000>;
};
};
};
};
TPS65910 Power Management Integrated Circuit
Required properties:
- compatible: "ti,tps65910" or "ti,tps65911"
- reg: I2C slave address
- interrupts: the interrupt outputs of the controller
- #gpio-cells: number of cells to describe a GPIO, this should be 2.
The first cell is the GPIO number.
The second cell is used to specify additional options <unused>.
- gpio-controller: mark the device as a GPIO controller
- #interrupt-cells: the number of cells to describe an IRQ, this should be 2.
The first cell is the IRQ number.
The second cell is the flags, encoded as the trigger masks from
Documentation/devicetree/bindings/interrupts.txt
- regulators: This is the list of child nodes that specify the regulator
initialization data for defined regulators. Not all regulators for the given
device need to be present. The definition for each of these nodes is defined
using the standard binding for regulators found at
Documentation/devicetree/bindings/regulator/regulator.txt.
The valid names for regulators are:
tps65910: vrtc, vio, vdd1, vdd2, vdd3, vdig1, vdig2, vpll, vdac, vaux1,
vaux2, vaux33, vmmc
tps65911: vrtc, vio, vdd1, vdd3, vddctrl, ldo1, ldo2, ldo3, ldo4, ldo5,
ldo6, ldo7, ldo8
Optional properties:
- ti,vmbch-threshold: (tps65911) main battery charged threshold
comparator. (see VMBCH_VSEL in TPS65910 datasheet)
- ti,vmbch2-threshold: (tps65911) main battery discharged threshold
comparator. (see VMBCH_VSEL in TPS65910 datasheet)
- ti,en-gpio-sleep: enable sleep control for gpios
There should be 9 entries here, one for each gpio.
Regulator Optional properties:
- ti,regulator-ext-sleep-control: enable external sleep
control through external inputs [0 (not enabled), 1 (EN1), 2 (EN2) or 4(EN3)]
If this property is not defined, it defaults to 0 (not enabled).
Example:
pmu: tps65910@d2 {
compatible = "ti,tps65910";
reg = <0xd2>;
interrupt-parent = <&intc>;
interrupts = < 0 118 0x04 >;
#gpio-cells = <2>;
gpio-controller;
#interrupt-cells = <2>;
interrupt-controller;
ti,vmbch-threshold = 0;
ti,vmbch2-threshold = 0;
ti,en-gpio-sleep = <0 0 1 0 0 0 0 0 0>;
regulators {
vdd1_reg: vdd1 {
regulator-min-microvolt = < 600000>;
regulator-max-microvolt = <1500000>;
regulator-always-on;
regulator-boot-on;
ti,regulator-ext-sleep-control = <0>;
};
vdd2_reg: vdd2 {
regulator-min-microvolt = < 600000>;
regulator-max-microvolt = <1500000>;
regulator-always-on;
regulator-boot-on;
ti,regulator-ext-sleep-control = <4>;
};
vddctrl_reg: vddctrl {
regulator-min-microvolt = < 600000>;
regulator-max-microvolt = <1400000>;
regulator-always-on;
regulator-boot-on;
ti,regulator-ext-sleep-control = <0>;
};
vio_reg: vio {
regulator-min-microvolt = <1500000>;
regulator-max-microvolt = <1800000>;
regulator-always-on;
regulator-boot-on;
ti,regulator-ext-sleep-control = <1>;
};
ldo1_reg: ldo1 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3300000>;
ti,regulator-ext-sleep-control = <0>;
};
ldo2_reg: ldo2 {
regulator-min-microvolt = <1050000>;
regulator-max-microvolt = <1050000>;
ti,regulator-ext-sleep-control = <0>;
};
ldo3_reg: ldo3 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3300000>;
ti,regulator-ext-sleep-control = <0>;
};
ldo4_reg: ldo4 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
ti,regulator-ext-sleep-control = <0>;
};
ldo5_reg: ldo5 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3300000>;
ti,regulator-ext-sleep-control = <0>;
};
ldo6_reg: ldo6 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
ti,regulator-ext-sleep-control = <0>;
};
ldo7_reg: ldo7 {
regulator-min-microvolt = <1200000>;
regulator-max-microvolt = <1200000>;
regulator-always-on;
regulator-boot-on;
ti,regulator-ext-sleep-control = <1>;
};
ldo8_reg: ldo8 {
regulator-min-microvolt = <1000000>;
regulator-max-microvolt = <3300000>;
regulator-always-on;
ti,regulator-ext-sleep-control = <1>;
};
};
};
Texas Instruments TWL6040 family
The TWL6040s are 8-channel high quality low-power audio codecs providing audio
and vibra functionality on OMAP4+ platforms.
They are connected ot the host processor via i2c for commands, McPDM for audio
data and commands.
Required properties:
- compatible : Must be "ti,twl6040";
- reg: must be 0x4b for i2c address
- interrupts: twl6040 has one interrupt line connecteded to the main SoC
- interrupt-parent: The parent interrupt controller
- twl6040,audpwron-gpio: Power on GPIO line for the twl6040
- vio-supply: Regulator for the twl6040 VIO supply
- v2v1-supply: Regulator for the twl6040 V2V1 supply
Optional properties, nodes:
- enable-active-high: To power on the twl6040 during boot.
Vibra functionality
Required properties:
- vddvibl-supply: Regulator for the left vibra motor
- vddvibr-supply: Regulator for the right vibra motor
- vibra { }: Configuration section for vibra parameters containing the following
properties:
- ti,vibldrv-res: Resistance parameter for left driver
- ti,vibrdrv-res: Resistance parameter for right driver
- ti,viblmotor-res: Resistance parameter for left motor
- ti,viblmotor-res: Resistance parameter for right motor
Optional properties within vibra { } section:
- vddvibl_uV: If the vddvibl default voltage need to be changed
- vddvibr_uV: If the vddvibr default voltage need to be changed
Example:
&i2c1 {
twl6040: twl@4b {
compatible = "ti,twl6040";
reg = <0x4b>;
interrupts = <0 119 4>;
interrupt-parent = <&gic>;
twl6040,audpwron-gpio = <&gpio4 31 0>;
vio-supply = <&v1v8>;
v2v1-supply = <&v2v1>;
enable-active-high;
/* regulators for vibra motor */
vddvibl-supply = <&vbat>;
vddvibr-supply = <&vbat>;
vibra {
/* Vibra driver, motor resistance parameters */
ti,vibldrv-res = <8>;
ti,vibrdrv-res = <3>;
ti,viblmotor-res = <10>;
ti,vibrmotor-res = <10>;
};
};
};
...@@ -60,7 +60,6 @@ ata *); ...@@ -60,7 +60,6 @@ ata *);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t); ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *); int (*removexattr) (struct dentry *, const char *);
void (*truncate_range)(struct inode *, loff_t, loff_t);
int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len); int (*fiemap)(struct inode *, struct fiemap_extent_info *, u64 start, u64 len);
locking rules: locking rules:
...@@ -87,7 +86,6 @@ setxattr: yes ...@@ -87,7 +86,6 @@ setxattr: yes
getxattr: no getxattr: no
listxattr: no listxattr: no
removexattr: yes removexattr: yes
truncate_range: yes
fiemap: no fiemap: no
Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on Additionally, ->rmdir(), ->unlink() and ->rename() have ->i_mutex on
victim. victim.
......
...@@ -743,6 +743,7 @@ Committed_AS: 100056 kB ...@@ -743,6 +743,7 @@ Committed_AS: 100056 kB
VmallocTotal: 112216 kB VmallocTotal: 112216 kB
VmallocUsed: 428 kB VmallocUsed: 428 kB
VmallocChunk: 111088 kB VmallocChunk: 111088 kB
AnonHugePages: 49152 kB
MemTotal: Total usable ram (i.e. physical ram minus a few reserved MemTotal: Total usable ram (i.e. physical ram minus a few reserved
bits and the kernel binary code) bits and the kernel binary code)
...@@ -776,6 +777,7 @@ VmallocChunk: 111088 kB ...@@ -776,6 +777,7 @@ VmallocChunk: 111088 kB
Dirty: Memory which is waiting to get written back to the disk Dirty: Memory which is waiting to get written back to the disk
Writeback: Memory which is actively being written back to the disk Writeback: Memory which is actively being written back to the disk
AnonPages: Non-file backed pages mapped into userspace page tables AnonPages: Non-file backed pages mapped into userspace page tables
AnonHugePages: Non-file backed huge pages mapped into userspace page tables
Mapped: files which have been mmaped, such as libraries Mapped: files which have been mmaped, such as libraries
Slab: in-kernel data structures cache Slab: in-kernel data structures cache
SReclaimable: Part of Slab, that might be reclaimed, such as caches SReclaimable: Part of Slab, that might be reclaimed, such as caches
......
...@@ -363,7 +363,6 @@ struct inode_operations { ...@@ -363,7 +363,6 @@ struct inode_operations {
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t); ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *); int (*removexattr) (struct dentry *, const char *);
void (*truncate_range)(struct inode *, loff_t, loff_t);
}; };
Again, all methods are called without any locks being held, unless Again, all methods are called without any locks being held, unless
...@@ -472,9 +471,6 @@ otherwise noted. ...@@ -472,9 +471,6 @@ otherwise noted.
removexattr: called by the VFS to remove an extended attribute from removexattr: called by the VFS to remove an extended attribute from
a file. This method is called by removexattr(2) system call. a file. This method is called by removexattr(2) system call.
truncate_range: a method provided by the underlying filesystem to truncate a
range of blocks , i.e. punch a hole somewhere in a file.
The Address Space Object The Address Space Object
======================== ========================
...@@ -760,7 +756,7 @@ struct file_operations ...@@ -760,7 +756,7 @@ struct file_operations
---------------------- ----------------------
This describes how the VFS can manipulate an open file. As of kernel This describes how the VFS can manipulate an open file. As of kernel
2.6.22, the following members are defined: 3.5, the following members are defined:
struct file_operations { struct file_operations {
struct module *owner; struct module *owner;
...@@ -790,6 +786,8 @@ struct file_operations { ...@@ -790,6 +786,8 @@ struct file_operations {
int (*flock) (struct file *, int, struct file_lock *); int (*flock) (struct file *, int, struct file_lock *);
ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int); ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, size_t, unsigned int);
ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int); ssize_t (*splice_read)(struct file *, struct pipe_inode_info *, size_t, unsigned int);
int (*setlease)(struct file *, long arg, struct file_lock **);
long (*fallocate)(struct file *, int mode, loff_t offset, loff_t len);
}; };
Again, all methods are called without any locks being held, unless Again, all methods are called without any locks being held, unless
...@@ -858,6 +856,11 @@ otherwise noted. ...@@ -858,6 +856,11 @@ otherwise noted.
splice_read: called by the VFS to splice data from file to a pipe. This splice_read: called by the VFS to splice data from file to a pipe. This
method is used by the splice(2) system call method is used by the splice(2) system call
setlease: called by the VFS to set or release a file lock lease.
setlease has the file_lock_lock held and must not sleep.
fallocate: called by the VFS to preallocate blocks or punch a hole.
Note that the file operations are implemented by the specific Note that the file operations are implemented by the specific
filesystem in which the inode resides. When opening a device node filesystem in which the inode resides. When opening a device node
(character or block special) most filesystems will call special (character or block special) most filesystems will call special
......
...@@ -166,6 +166,68 @@ behavior. So to make them effective you need to restart any ...@@ -166,6 +166,68 @@ behavior. So to make them effective you need to restart any
application that could have been using hugepages. This also applies to application that could have been using hugepages. This also applies to
the regions registered in khugepaged. the regions registered in khugepaged.
== Monitoring usage ==
The number of transparent huge pages currently used by the system is
available by reading the AnonHugePages field in /proc/meminfo. To
identify what applications are using transparent huge pages, it is
necessary to read /proc/PID/smaps and count the AnonHugePages fields
for each mapping. Note that reading the smaps file is expensive and
reading it frequently will incur overhead.
There are a number of counters in /proc/vmstat that may be used to
monitor how successfully the system is providing huge pages for use.
thp_fault_alloc is incremented every time a huge page is successfully
allocated to handle a page fault. This applies to both the
first time a page is faulted and for COW faults.
thp_collapse_alloc is incremented by khugepaged when it has found
a range of pages to collapse into one huge page and has
successfully allocated a new huge page to store the data.
thp_fault_fallback is incremented if a page fault fails to allocate
a huge page and instead falls back to using small pages.
thp_collapse_alloc_failed is incremented if khugepaged found a range
of pages that should be collapsed into one huge page but failed
the allocation.
thp_split is incremented every time a huge page is split into base
pages. This can happen for a variety of reasons but a common
reason is that a huge page is old and is being reclaimed.
As the system ages, allocating huge pages may be expensive as the
system uses memory compaction to copy data around memory to free a
huge page for use. There are some counters in /proc/vmstat to help
monitor this overhead.
compact_stall is incremented every time a process stalls to run
memory compaction so that a huge page is free for use.
compact_success is incremented if the system compacted memory and
freed a huge page for use.
compact_fail is incremented if the system tries to compact memory
but failed.
compact_pages_moved is incremented each time a page is moved. If
this value is increasing rapidly, it implies that the system
is copying a lot of data to satisfy the huge page allocation.
It is possible that the cost of copying exceeds any savings
from reduced TLB misses.
compact_pagemigrate_failed is incremented when the underlying mechanism
for moving a page failed.
compact_blocks_moved is incremented each time memory compaction examines
a huge page aligned range of pages.
It is possible to establish how long the stalls were using the function
tracer to record how long was spent in __alloc_pages_nodemask and
using the mm_page_alloc tracepoint to identify which allocations were
for huge pages.
== get_user_pages and follow_page == == get_user_pages and follow_page ==
get_user_pages and follow_page if run on a hugepage, will return the get_user_pages and follow_page if run on a hugepage, will return the
......
...@@ -3382,6 +3382,12 @@ W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html ...@@ -3382,6 +3382,12 @@ W: http://www.developer.ibm.com/welcome/netfinity/serveraid.html
S: Supported S: Supported
F: drivers/scsi/ips.* F: drivers/scsi/ips.*
ICH LPC AND GPIO DRIVER
M: Peter Tyser <ptyser@xes-inc.com>
S: Maintained
F: drivers/mfd/lpc_ich.c
F: drivers/gpio/gpio-ich.c
IDE SUBSYSTEM IDE SUBSYSTEM
M: "David S. Miller" <davem@davemloft.net> M: "David S. Miller" <davem@davemloft.net>
L: linux-ide@vger.kernel.org L: linux-ide@vger.kernel.org
......
...@@ -206,7 +206,7 @@ static struct resource ab8500_resources[] = { ...@@ -206,7 +206,7 @@ static struct resource ab8500_resources[] = {
}; };
struct platform_device ab8500_device = { struct platform_device ab8500_device = {
.name = "ab8500-i2c", .name = "ab8500-core",
.id = 0, .id = 0,
.dev = { .dev = {
.platform_data = &ab8500_platdata, .platform_data = &ab8500_platdata,
......
...@@ -40,6 +40,7 @@ config CRIS ...@@ -40,6 +40,7 @@ config CRIS
bool bool
default y default y
select HAVE_IDE select HAVE_IDE
select GENERIC_ATOMIC64
select HAVE_GENERIC_HARDIRQS select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW select GENERIC_IRQ_SHOW
select GENERIC_IOMAP select GENERIC_IOMAP
......
...@@ -31,6 +31,56 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte) ...@@ -31,6 +31,56 @@ static inline void native_set_pte(pte_t *ptep, pte_t pte)
ptep->pte_low = pte.pte_low; ptep->pte_low = pte.pte_low;
} }
#define pmd_read_atomic pmd_read_atomic
/*
* pte_offset_map_lock on 32bit PAE kernels was reading the pmd_t with
* a "*pmdp" dereference done by gcc. Problem is, in certain places
* where pte_offset_map_lock is called, concurrent page faults are
* allowed, if the mmap_sem is hold for reading. An example is mincore
* vs page faults vs MADV_DONTNEED. On the page fault side
* pmd_populate rightfully does a set_64bit, but if we're reading the
* pmd_t with a "*pmdp" on the mincore side, a SMP race can happen
* because gcc will not read the 64bit of the pmd atomically. To fix
* this all places running pmd_offset_map_lock() while holding the
* mmap_sem in read mode, shall read the pmdp pointer using this
* function to know if the pmd is null nor not, and in turn to know if
* they can run pmd_offset_map_lock or pmd_trans_huge or other pmd
* operations.
*
* Without THP if the mmap_sem is hold for reading, the
* pmd can only transition from null to not null while pmd_read_atomic runs.
* So there's no need of literally reading it atomically.
*
* With THP if the mmap_sem is hold for reading, the pmd can become
* THP or null or point to a pte (and in turn become "stable") at any
* time under pmd_read_atomic, so it's mandatory to read it atomically
* with cmpxchg8b.
*/
#ifndef CONFIG_TRANSPARENT_HUGEPAGE
static inline pmd_t pmd_read_atomic(pmd_t *pmdp)
{
pmdval_t ret;
u32 *tmp = (u32 *)pmdp;
ret = (pmdval_t) (*tmp);
if (ret) {
/*
* If the low part is null, we must not read the high part
* or we can end up with a partial pmd.
*/
smp_rmb();
ret |= ((pmdval_t)*(tmp + 1)) << 32;
}
return (pmd_t) { ret };
}
#else /* CONFIG_TRANSPARENT_HUGEPAGE */
static inline pmd_t pmd_read_atomic(pmd_t *pmdp)
{
return (pmd_t) { atomic64_read((atomic64_t *)pmdp) };
}
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte) static inline void native_set_pte_atomic(pte_t *ptep, pte_t pte)
{ {
set_64bit((unsigned long long *)(ptep), native_pte_val(pte)); set_64bit((unsigned long long *)(ptep), native_pte_val(pte));
......
/*
* Header file for STMicroelectronics ConneXt (STA2X11) IOHub
*/
#ifndef __ASM_STA2X11_H
#define __ASM_STA2X11_H
#include <linux/pci.h>
/* This needs to be called from the MFD to configure its sub-devices */
struct sta2x11_instance *sta2x11_get_instance(struct pci_dev *pdev);
#endif /* __ASM_STA2X11_H */
...@@ -113,7 +113,9 @@ static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size, ...@@ -113,7 +113,9 @@ static void __init __e820_add_region(struct e820map *e820x, u64 start, u64 size,
int x = e820x->nr_map; int x = e820x->nr_map;
if (x >= ARRAY_SIZE(e820x->map)) { if (x >= ARRAY_SIZE(e820x->map)) {
printk(KERN_ERR "Ooops! Too many entries in the memory map!\n"); printk(KERN_ERR "e820: too many entries; ignoring [mem %#010llx-%#010llx]\n",
(unsigned long long) start,
(unsigned long long) (start + size - 1));
return; return;
} }
...@@ -133,19 +135,19 @@ static void __init e820_print_type(u32 type) ...@@ -133,19 +135,19 @@ static void __init e820_print_type(u32 type)
switch (type) { switch (type) {
case E820_RAM: case E820_RAM:
case E820_RESERVED_KERN: case E820_RESERVED_KERN:
printk(KERN_CONT "(usable)"); printk(KERN_CONT "usable");
break; break;
case E820_RESERVED: case E820_RESERVED:
printk(KERN_CONT "(reserved)"); printk(KERN_CONT "reserved");
break; break;
case E820_ACPI: case E820_ACPI:
printk(KERN_CONT "(ACPI data)"); printk(KERN_CONT "ACPI data");
break; break;
case E820_NVS: case E820_NVS:
printk(KERN_CONT "(ACPI NVS)"); printk(KERN_CONT "ACPI NVS");
break; break;
case E820_UNUSABLE: case E820_UNUSABLE:
printk(KERN_CONT "(unusable)"); printk(KERN_CONT "unusable");
break; break;
default: default:
printk(KERN_CONT "type %u", type); printk(KERN_CONT "type %u", type);
...@@ -158,10 +160,10 @@ void __init e820_print_map(char *who) ...@@ -158,10 +160,10 @@ void __init e820_print_map(char *who)
int i; int i;
for (i = 0; i < e820.nr_map; i++) { for (i = 0; i < e820.nr_map; i++) {
printk(KERN_INFO " %s: %016Lx - %016Lx ", who, printk(KERN_INFO "%s: [mem %#018Lx-%#018Lx] ", who,
(unsigned long long) e820.map[i].addr, (unsigned long long) e820.map[i].addr,
(unsigned long long) (unsigned long long)
(e820.map[i].addr + e820.map[i].size)); (e820.map[i].addr + e820.map[i].size - 1));
e820_print_type(e820.map[i].type); e820_print_type(e820.map[i].type);
printk(KERN_CONT "\n"); printk(KERN_CONT "\n");
} }
...@@ -428,9 +430,8 @@ static u64 __init __e820_update_range(struct e820map *e820x, u64 start, ...@@ -428,9 +430,8 @@ static u64 __init __e820_update_range(struct e820map *e820x, u64 start,
size = ULLONG_MAX - start; size = ULLONG_MAX - start;
end = start + size; end = start + size;
printk(KERN_DEBUG "e820 update range: %016Lx - %016Lx ", printk(KERN_DEBUG "e820: update [mem %#010Lx-%#010Lx] ",
(unsigned long long) start, (unsigned long long) start, (unsigned long long) (end - 1));
(unsigned long long) end);
e820_print_type(old_type); e820_print_type(old_type);
printk(KERN_CONT " ==> "); printk(KERN_CONT " ==> ");
e820_print_type(new_type); e820_print_type(new_type);
...@@ -509,9 +510,8 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type, ...@@ -509,9 +510,8 @@ u64 __init e820_remove_range(u64 start, u64 size, unsigned old_type,
size = ULLONG_MAX - start; size = ULLONG_MAX - start;
end = start + size; end = start + size;
printk(KERN_DEBUG "e820 remove range: %016Lx - %016Lx ", printk(KERN_DEBUG "e820: remove [mem %#010Lx-%#010Lx] ",
(unsigned long long) start, (unsigned long long) start, (unsigned long long) (end - 1));
(unsigned long long) end);
if (checktype) if (checktype)
e820_print_type(old_type); e820_print_type(old_type);
printk(KERN_CONT "\n"); printk(KERN_CONT "\n");
...@@ -567,7 +567,7 @@ void __init update_e820(void) ...@@ -567,7 +567,7 @@ void __init update_e820(void)
if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map)) if (sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &nr_map))
return; return;
e820.nr_map = nr_map; e820.nr_map = nr_map;
printk(KERN_INFO "modified physical RAM map:\n"); printk(KERN_INFO "e820: modified physical RAM map:\n");
e820_print_map("modified"); e820_print_map("modified");
} }
static void __init update_e820_saved(void) static void __init update_e820_saved(void)
...@@ -637,8 +637,8 @@ __init void e820_setup_gap(void) ...@@ -637,8 +637,8 @@ __init void e820_setup_gap(void)
if (!found) { if (!found) {
gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024; gapstart = (max_pfn << PAGE_SHIFT) + 1024*1024;
printk(KERN_ERR printk(KERN_ERR
"PCI: Warning: Cannot find a gap in the 32bit address range\n" "e820: cannot find a gap in the 32bit address range\n"
"PCI: Unassigned devices with 32bit resource registers may break!\n"); "e820: PCI devices with unassigned 32bit BARs may break!\n");
} }
#endif #endif
...@@ -648,8 +648,8 @@ __init void e820_setup_gap(void) ...@@ -648,8 +648,8 @@ __init void e820_setup_gap(void)
pci_mem_start = gapstart; pci_mem_start = gapstart;
printk(KERN_INFO printk(KERN_INFO
"Allocating PCI resources starting at %lx (gap: %lx:%lx)\n", "e820: [mem %#010lx-%#010lx] available for PCI devices\n",
pci_mem_start, gapstart, gapsize); gapstart, gapstart + gapsize - 1);
} }
/** /**
...@@ -667,7 +667,7 @@ void __init parse_e820_ext(struct setup_data *sdata) ...@@ -667,7 +667,7 @@ void __init parse_e820_ext(struct setup_data *sdata)
extmap = (struct e820entry *)(sdata->data); extmap = (struct e820entry *)(sdata->data);
__append_e820_map(extmap, entries); __append_e820_map(extmap, entries);
sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map); sanitize_e820_map(e820.map, ARRAY_SIZE(e820.map), &e820.nr_map);
printk(KERN_INFO "extended physical RAM map:\n"); printk(KERN_INFO "e820: extended physical RAM map:\n");
e820_print_map("extended"); e820_print_map("extended");
} }
...@@ -734,7 +734,7 @@ u64 __init early_reserve_e820(u64 size, u64 align) ...@@ -734,7 +734,7 @@ u64 __init early_reserve_e820(u64 size, u64 align)
addr = __memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE); addr = __memblock_alloc_base(size, align, MEMBLOCK_ALLOC_ACCESSIBLE);
if (addr) { if (addr) {
e820_update_range_saved(addr, size, E820_RAM, E820_RESERVED); e820_update_range_saved(addr, size, E820_RAM, E820_RESERVED);
printk(KERN_INFO "update e820_saved for early_reserve_e820\n"); printk(KERN_INFO "e820: update e820_saved for early_reserve_e820\n");
update_e820_saved(); update_e820_saved();
} }
...@@ -784,7 +784,7 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type) ...@@ -784,7 +784,7 @@ static unsigned long __init e820_end_pfn(unsigned long limit_pfn, unsigned type)
if (last_pfn > max_arch_pfn) if (last_pfn > max_arch_pfn)
last_pfn = max_arch_pfn; last_pfn = max_arch_pfn;
printk(KERN_INFO "last_pfn = %#lx max_arch_pfn = %#lx\n", printk(KERN_INFO "e820: last_pfn = %#lx max_arch_pfn = %#lx\n",
last_pfn, max_arch_pfn); last_pfn, max_arch_pfn);
return last_pfn; return last_pfn;
} }
...@@ -888,7 +888,7 @@ void __init finish_e820_parsing(void) ...@@ -888,7 +888,7 @@ void __init finish_e820_parsing(void)
early_panic("Invalid user supplied memory map"); early_panic("Invalid user supplied memory map");
e820.nr_map = nr; e820.nr_map = nr;
printk(KERN_INFO "user-defined physical RAM map:\n"); printk(KERN_INFO "e820: user-defined physical RAM map:\n");
e820_print_map("user"); e820_print_map("user");
} }
} }
...@@ -996,8 +996,9 @@ void __init e820_reserve_resources_late(void) ...@@ -996,8 +996,9 @@ void __init e820_reserve_resources_late(void)
end = MAX_RESOURCE_SIZE; end = MAX_RESOURCE_SIZE;
if (start >= end) if (start >= end)
continue; continue;
printk(KERN_DEBUG "reserve RAM buffer: %016llx - %016llx ", printk(KERN_DEBUG
start, end); "e820: reserve RAM buffer [mem %#010llx-%#010llx]\n",
start, end);
reserve_region_with_split(&iomem_resource, start, end, reserve_region_with_split(&iomem_resource, start, end,
"RAM buffer"); "RAM buffer");
} }
...@@ -1047,7 +1048,7 @@ void __init setup_memory_map(void) ...@@ -1047,7 +1048,7 @@ void __init setup_memory_map(void)
who = x86_init.resources.memory_setup(); who = x86_init.resources.memory_setup();
memcpy(&e820_saved, &e820, sizeof(struct e820map)); memcpy(&e820_saved, &e820, sizeof(struct e820map));
printk(KERN_INFO "BIOS-provided physical RAM map:\n"); printk(KERN_INFO "e820: BIOS-provided physical RAM map:\n");
e820_print_map(who); e820_print_map(who);
} }
......
...@@ -568,8 +568,8 @@ static int __init smp_scan_config(unsigned long base, unsigned long length) ...@@ -568,8 +568,8 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
struct mpf_intel *mpf; struct mpf_intel *mpf;
unsigned long mem; unsigned long mem;
apic_printk(APIC_VERBOSE, "Scan SMP from %p for %ld bytes.\n", apic_printk(APIC_VERBOSE, "Scan for SMP in [mem %#010lx-%#010lx]\n",
bp, length); base, base + length - 1);
BUILD_BUG_ON(sizeof(*mpf) != 16); BUILD_BUG_ON(sizeof(*mpf) != 16);
while (length > 0) { while (length > 0) {
...@@ -584,8 +584,10 @@ static int __init smp_scan_config(unsigned long base, unsigned long length) ...@@ -584,8 +584,10 @@ static int __init smp_scan_config(unsigned long base, unsigned long length)
#endif #endif
mpf_found = mpf; mpf_found = mpf;
printk(KERN_INFO "found SMP MP-table at [%p] %llx\n", printk(KERN_INFO "found SMP MP-table at [mem %#010llx-%#010llx] mapped at [%p]\n",
mpf, (u64)virt_to_phys(mpf)); (unsigned long long) virt_to_phys(mpf),
(unsigned long long) virt_to_phys(mpf) +
sizeof(*mpf) - 1, mpf);
mem = virt_to_phys(mpf); mem = virt_to_phys(mpf);
memblock_reserve(mem, sizeof(*mpf)); memblock_reserve(mem, sizeof(*mpf));
......
...@@ -334,8 +334,8 @@ static void __init relocate_initrd(void) ...@@ -334,8 +334,8 @@ static void __init relocate_initrd(void)
memblock_reserve(ramdisk_here, area_size); memblock_reserve(ramdisk_here, area_size);
initrd_start = ramdisk_here + PAGE_OFFSET; initrd_start = ramdisk_here + PAGE_OFFSET;
initrd_end = initrd_start + ramdisk_size; initrd_end = initrd_start + ramdisk_size;
printk(KERN_INFO "Allocated new RAMDISK: %08llx - %08llx\n", printk(KERN_INFO "Allocated new RAMDISK: [mem %#010llx-%#010llx]\n",
ramdisk_here, ramdisk_here + ramdisk_size); ramdisk_here, ramdisk_here + ramdisk_size - 1);
q = (char *)initrd_start; q = (char *)initrd_start;
...@@ -366,8 +366,8 @@ static void __init relocate_initrd(void) ...@@ -366,8 +366,8 @@ static void __init relocate_initrd(void)
/* high pages is not converted by early_res_to_bootmem */ /* high pages is not converted by early_res_to_bootmem */
ramdisk_image = boot_params.hdr.ramdisk_image; ramdisk_image = boot_params.hdr.ramdisk_image;
ramdisk_size = boot_params.hdr.ramdisk_size; ramdisk_size = boot_params.hdr.ramdisk_size;
printk(KERN_INFO "Move RAMDISK from %016llx - %016llx to" printk(KERN_INFO "Move RAMDISK from [mem %#010llx-%#010llx] to"
" %08llx - %08llx\n", " [mem %#010llx-%#010llx]\n",
ramdisk_image, ramdisk_image + ramdisk_size - 1, ramdisk_image, ramdisk_image + ramdisk_size - 1,
ramdisk_here, ramdisk_here + ramdisk_size - 1); ramdisk_here, ramdisk_here + ramdisk_size - 1);
} }
...@@ -392,8 +392,8 @@ static void __init reserve_initrd(void) ...@@ -392,8 +392,8 @@ static void __init reserve_initrd(void)
ramdisk_size, end_of_lowmem>>1); ramdisk_size, end_of_lowmem>>1);
} }
printk(KERN_INFO "RAMDISK: %08llx - %08llx\n", ramdisk_image, printk(KERN_INFO "RAMDISK: [mem %#010llx-%#010llx]\n", ramdisk_image,
ramdisk_end); ramdisk_end - 1);
if (ramdisk_end <= end_of_lowmem) { if (ramdisk_end <= end_of_lowmem) {
...@@ -906,8 +906,8 @@ void __init setup_arch(char **cmdline_p) ...@@ -906,8 +906,8 @@ void __init setup_arch(char **cmdline_p)
setup_bios_corruption_check(); setup_bios_corruption_check();
#endif #endif
printk(KERN_DEBUG "initial memory mapped : 0 - %08lx\n", printk(KERN_DEBUG "initial memory mapped: [mem 0x00000000-%#010lx]\n",
max_pfn_mapped<<PAGE_SHIFT); (max_pfn_mapped<<PAGE_SHIFT) - 1);
setup_trampolines(); setup_trampolines();
......
...@@ -84,8 +84,9 @@ static void __init find_early_table_space(struct map_range *mr, unsigned long en ...@@ -84,8 +84,9 @@ static void __init find_early_table_space(struct map_range *mr, unsigned long en
pgt_buf_end = pgt_buf_start; pgt_buf_end = pgt_buf_start;
pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT); pgt_buf_top = pgt_buf_start + (tables >> PAGE_SHIFT);
printk(KERN_DEBUG "kernel direct mapping tables up to %lx @ %lx-%lx\n", printk(KERN_DEBUG "kernel direct mapping tables up to %#lx @ [mem %#010lx-%#010lx]\n",
end, pgt_buf_start << PAGE_SHIFT, pgt_buf_top << PAGE_SHIFT); end - 1, pgt_buf_start << PAGE_SHIFT,
(pgt_buf_top << PAGE_SHIFT) - 1);
} }
void __init native_pagetable_reserve(u64 start, u64 end) void __init native_pagetable_reserve(u64 start, u64 end)
...@@ -132,7 +133,8 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, ...@@ -132,7 +133,8 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
int nr_range, i; int nr_range, i;
int use_pse, use_gbpages; int use_pse, use_gbpages;
printk(KERN_INFO "init_memory_mapping: %016lx-%016lx\n", start, end); printk(KERN_INFO "init_memory_mapping: [mem %#010lx-%#010lx]\n",
start, end - 1);
#if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK) #if defined(CONFIG_DEBUG_PAGEALLOC) || defined(CONFIG_KMEMCHECK)
/* /*
...@@ -251,8 +253,8 @@ unsigned long __init_refok init_memory_mapping(unsigned long start, ...@@ -251,8 +253,8 @@ unsigned long __init_refok init_memory_mapping(unsigned long start,
} }
for (i = 0; i < nr_range; i++) for (i = 0; i < nr_range; i++)
printk(KERN_DEBUG " %010lx - %010lx page %s\n", printk(KERN_DEBUG " [mem %#010lx-%#010lx] page %s\n",
mr[i].start, mr[i].end, mr[i].start, mr[i].end - 1,
(mr[i].page_size_mask & (1<<PG_LEVEL_1G))?"1G":( (mr[i].page_size_mask & (1<<PG_LEVEL_1G))?"1G":(
(mr[i].page_size_mask & (1<<PG_LEVEL_2M))?"2M":"4k")); (mr[i].page_size_mask & (1<<PG_LEVEL_2M))?"2M":"4k"));
...@@ -350,8 +352,8 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end) ...@@ -350,8 +352,8 @@ void free_init_pages(char *what, unsigned long begin, unsigned long end)
* create a kernel page fault: * create a kernel page fault:
*/ */
#ifdef CONFIG_DEBUG_PAGEALLOC #ifdef CONFIG_DEBUG_PAGEALLOC
printk(KERN_INFO "debug: unmapping init memory %08lx..%08lx\n", printk(KERN_INFO "debug: unmapping init [mem %#010lx-%#010lx]\n",
begin, end); begin, end - 1);
set_memory_np(begin, (end - begin) >> PAGE_SHIFT); set_memory_np(begin, (end - begin) >> PAGE_SHIFT);
#else #else
/* /*
......
...@@ -141,8 +141,8 @@ static int __init numa_add_memblk_to(int nid, u64 start, u64 end, ...@@ -141,8 +141,8 @@ static int __init numa_add_memblk_to(int nid, u64 start, u64 end,
/* whine about and ignore invalid blks */ /* whine about and ignore invalid blks */
if (start > end || nid < 0 || nid >= MAX_NUMNODES) { if (start > end || nid < 0 || nid >= MAX_NUMNODES) {
pr_warning("NUMA: Warning: invalid memblk node %d (%Lx-%Lx)\n", pr_warning("NUMA: Warning: invalid memblk node %d [mem %#010Lx-%#010Lx]\n",
nid, start, end); nid, start, end - 1);
return 0; return 0;
} }
...@@ -210,8 +210,8 @@ static void __init setup_node_data(int nid, u64 start, u64 end) ...@@ -210,8 +210,8 @@ static void __init setup_node_data(int nid, u64 start, u64 end)
start = roundup(start, ZONE_ALIGN); start = roundup(start, ZONE_ALIGN);
printk(KERN_INFO "Initmem setup node %d %016Lx-%016Lx\n", printk(KERN_INFO "Initmem setup node %d [mem %#010Lx-%#010Lx]\n",
nid, start, end); nid, start, end - 1);
/* /*
* Allocate node data. Try remap allocator first, node-local * Allocate node data. Try remap allocator first, node-local
...@@ -232,7 +232,7 @@ static void __init setup_node_data(int nid, u64 start, u64 end) ...@@ -232,7 +232,7 @@ static void __init setup_node_data(int nid, u64 start, u64 end)
} }
/* report and initialize */ /* report and initialize */
printk(KERN_INFO " NODE_DATA [%016Lx - %016Lx]%s\n", printk(KERN_INFO " NODE_DATA [mem %#010Lx-%#010Lx]%s\n",
nd_pa, nd_pa + nd_size - 1, remapped ? " (remapped)" : ""); nd_pa, nd_pa + nd_size - 1, remapped ? " (remapped)" : "");
tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT); tnid = early_pfn_to_nid(nd_pa >> PAGE_SHIFT);
if (!remapped && tnid != nid) if (!remapped && tnid != nid)
...@@ -291,14 +291,14 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi) ...@@ -291,14 +291,14 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi)
*/ */
if (bi->end > bj->start && bi->start < bj->end) { if (bi->end > bj->start && bi->start < bj->end) {
if (bi->nid != bj->nid) { if (bi->nid != bj->nid) {
pr_err("NUMA: node %d (%Lx-%Lx) overlaps with node %d (%Lx-%Lx)\n", pr_err("NUMA: node %d [mem %#010Lx-%#010Lx] overlaps with node %d [mem %#010Lx-%#010Lx]\n",
bi->nid, bi->start, bi->end, bi->nid, bi->start, bi->end - 1,
bj->nid, bj->start, bj->end); bj->nid, bj->start, bj->end - 1);
return -EINVAL; return -EINVAL;
} }
pr_warning("NUMA: Warning: node %d (%Lx-%Lx) overlaps with itself (%Lx-%Lx)\n", pr_warning("NUMA: Warning: node %d [mem %#010Lx-%#010Lx] overlaps with itself [mem %#010Lx-%#010Lx]\n",
bi->nid, bi->start, bi->end, bi->nid, bi->start, bi->end - 1,
bj->start, bj->end); bj->start, bj->end - 1);
} }
/* /*
...@@ -320,9 +320,9 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi) ...@@ -320,9 +320,9 @@ int __init numa_cleanup_meminfo(struct numa_meminfo *mi)
} }
if (k < mi->nr_blks) if (k < mi->nr_blks)
continue; continue;
printk(KERN_INFO "NUMA: Node %d [%Lx,%Lx) + [%Lx,%Lx) -> [%Lx,%Lx)\n", printk(KERN_INFO "NUMA: Node %d [mem %#010Lx-%#010Lx] + [mem %#010Lx-%#010Lx] -> [mem %#010Lx-%#010Lx]\n",
bi->nid, bi->start, bi->end, bj->start, bj->end, bi->nid, bi->start, bi->end - 1, bj->start,
start, end); bj->end - 1, start, end - 1);
bi->start = start; bi->start = start;
bi->end = end; bi->end = end;
numa_remove_memblk_from(j--, mi); numa_remove_memblk_from(j--, mi);
...@@ -616,8 +616,8 @@ static int __init dummy_numa_init(void) ...@@ -616,8 +616,8 @@ static int __init dummy_numa_init(void)
{ {
printk(KERN_INFO "%s\n", printk(KERN_INFO "%s\n",
numa_off ? "NUMA turned off" : "No NUMA configuration found"); numa_off ? "NUMA turned off" : "No NUMA configuration found");
printk(KERN_INFO "Faking a node at %016Lx-%016Lx\n", printk(KERN_INFO "Faking a node at [mem %#018Lx-%#018Lx]\n",
0LLU, PFN_PHYS(max_pfn)); 0LLU, PFN_PHYS(max_pfn) - 1);
node_set(0, numa_nodes_parsed); node_set(0, numa_nodes_parsed);
numa_add_memblk(0, 0, PFN_PHYS(max_pfn)); numa_add_memblk(0, 0, PFN_PHYS(max_pfn));
......
...@@ -68,8 +68,8 @@ static int __init emu_setup_memblk(struct numa_meminfo *ei, ...@@ -68,8 +68,8 @@ static int __init emu_setup_memblk(struct numa_meminfo *ei,
numa_remove_memblk_from(phys_blk, pi); numa_remove_memblk_from(phys_blk, pi);
} }
printk(KERN_INFO "Faking node %d at %016Lx-%016Lx (%LuMB)\n", nid, printk(KERN_INFO "Faking node %d at [mem %#018Lx-%#018Lx] (%LuMB)\n",
eb->start, eb->end, (eb->end - eb->start) >> 20); nid, eb->start, eb->end - 1, (eb->end - eb->start) >> 20);
return 0; return 0;
} }
......
...@@ -209,9 +209,8 @@ static int reserve_ram_pages_type(u64 start, u64 end, unsigned long req_type, ...@@ -209,9 +209,8 @@ static int reserve_ram_pages_type(u64 start, u64 end, unsigned long req_type,
page = pfn_to_page(pfn); page = pfn_to_page(pfn);
type = get_page_memtype(page); type = get_page_memtype(page);
if (type != -1) { if (type != -1) {
printk(KERN_INFO "reserve_ram_pages_type failed " printk(KERN_INFO "reserve_ram_pages_type failed [mem %#010Lx-%#010Lx], track 0x%lx, req 0x%lx\n",
"0x%Lx-0x%Lx, track 0x%lx, req 0x%lx\n", start, end - 1, type, req_type);
start, end, type, req_type);
if (new_type) if (new_type)
*new_type = type; *new_type = type;
...@@ -314,9 +313,9 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, ...@@ -314,9 +313,9 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
err = rbt_memtype_check_insert(new, new_type); err = rbt_memtype_check_insert(new, new_type);
if (err) { if (err) {
printk(KERN_INFO "reserve_memtype failed 0x%Lx-0x%Lx, " printk(KERN_INFO "reserve_memtype failed [mem %#010Lx-%#010Lx], track %s, req %s\n",
"track %s, req %s\n", start, end - 1,
start, end, cattr_name(new->type), cattr_name(req_type)); cattr_name(new->type), cattr_name(req_type));
kfree(new); kfree(new);
spin_unlock(&memtype_lock); spin_unlock(&memtype_lock);
...@@ -325,8 +324,8 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type, ...@@ -325,8 +324,8 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
spin_unlock(&memtype_lock); spin_unlock(&memtype_lock);
dprintk("reserve_memtype added 0x%Lx-0x%Lx, track %s, req %s, ret %s\n", dprintk("reserve_memtype added [mem %#010Lx-%#010Lx], track %s, req %s, ret %s\n",
start, end, cattr_name(new->type), cattr_name(req_type), start, end - 1, cattr_name(new->type), cattr_name(req_type),
new_type ? cattr_name(*new_type) : "-"); new_type ? cattr_name(*new_type) : "-");
return err; return err;
...@@ -360,14 +359,14 @@ int free_memtype(u64 start, u64 end) ...@@ -360,14 +359,14 @@ int free_memtype(u64 start, u64 end)
spin_unlock(&memtype_lock); spin_unlock(&memtype_lock);
if (!entry) { if (!entry) {
printk(KERN_INFO "%s:%d freeing invalid memtype %Lx-%Lx\n", printk(KERN_INFO "%s:%d freeing invalid memtype [mem %#010Lx-%#010Lx]\n",
current->comm, current->pid, start, end); current->comm, current->pid, start, end - 1);
return -EINVAL; return -EINVAL;
} }
kfree(entry); kfree(entry);
dprintk("free_memtype request 0x%Lx-0x%Lx\n", start, end); dprintk("free_memtype request [mem %#010Lx-%#010Lx]\n", start, end - 1);
return 0; return 0;
} }
...@@ -491,9 +490,8 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size) ...@@ -491,9 +490,8 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
while (cursor < to) { while (cursor < to) {
if (!devmem_is_allowed(pfn)) { if (!devmem_is_allowed(pfn)) {
printk(KERN_INFO printk(KERN_INFO "Program %s tried to access /dev/mem between [mem %#010Lx-%#010Lx]\n",
"Program %s tried to access /dev/mem between %Lx->%Lx.\n", current->comm, from, to - 1);
current->comm, from, to);
return 0; return 0;
} }
cursor += PAGE_SIZE; cursor += PAGE_SIZE;
...@@ -554,12 +552,11 @@ int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags) ...@@ -554,12 +552,11 @@ int kernel_map_sync_memtype(u64 base, unsigned long size, unsigned long flags)
size; size;
if (ioremap_change_attr((unsigned long)__va(base), id_sz, flags) < 0) { if (ioremap_change_attr((unsigned long)__va(base), id_sz, flags) < 0) {
printk(KERN_INFO printk(KERN_INFO "%s:%d ioremap_change_attr failed %s "
"%s:%d ioremap_change_attr failed %s " "for [mem %#010Lx-%#010Lx]\n",
"for %Lx-%Lx\n",
current->comm, current->pid, current->comm, current->pid,
cattr_name(flags), cattr_name(flags),
base, (unsigned long long)(base + size)); base, (unsigned long long)(base + size-1));
return -EINVAL; return -EINVAL;
} }
return 0; return 0;
...@@ -591,12 +588,11 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, ...@@ -591,12 +588,11 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
flags = lookup_memtype(paddr); flags = lookup_memtype(paddr);
if (want_flags != flags) { if (want_flags != flags) {
printk(KERN_WARNING printk(KERN_WARNING "%s:%d map pfn RAM range req %s for [mem %#010Lx-%#010Lx], got %s\n",
"%s:%d map pfn RAM range req %s for %Lx-%Lx, got %s\n",
current->comm, current->pid, current->comm, current->pid,
cattr_name(want_flags), cattr_name(want_flags),
(unsigned long long)paddr, (unsigned long long)paddr,
(unsigned long long)(paddr + size), (unsigned long long)(paddr + size - 1),
cattr_name(flags)); cattr_name(flags));
*vma_prot = __pgprot((pgprot_val(*vma_prot) & *vma_prot = __pgprot((pgprot_val(*vma_prot) &
(~_PAGE_CACHE_MASK)) | (~_PAGE_CACHE_MASK)) |
...@@ -614,11 +610,11 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot, ...@@ -614,11 +610,11 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
!is_new_memtype_allowed(paddr, size, want_flags, flags)) { !is_new_memtype_allowed(paddr, size, want_flags, flags)) {
free_memtype(paddr, paddr + size); free_memtype(paddr, paddr + size);
printk(KERN_ERR "%s:%d map pfn expected mapping type %s" printk(KERN_ERR "%s:%d map pfn expected mapping type %s"
" for %Lx-%Lx, got %s\n", " for [mem %#010Lx-%#010Lx], got %s\n",
current->comm, current->pid, current->comm, current->pid,
cattr_name(want_flags), cattr_name(want_flags),
(unsigned long long)paddr, (unsigned long long)paddr,
(unsigned long long)(paddr + size), (unsigned long long)(paddr + size - 1),
cattr_name(flags)); cattr_name(flags));
return -EINVAL; return -EINVAL;
} }
......
...@@ -176,8 +176,9 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) ...@@ -176,8 +176,9 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma)
return; return;
} }
printk(KERN_INFO "SRAT: Node %u PXM %u %Lx-%Lx\n", node, pxm, printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n",
start, end); node, pxm,
(unsigned long long) start, (unsigned long long) end - 1);
} }
void __init acpi_numa_arch_fixup(void) {} void __init acpi_numa_arch_fixup(void) {}
......
...@@ -592,11 +592,9 @@ static ssize_t print_nodes_state(enum node_states state, char *buf) ...@@ -592,11 +592,9 @@ static ssize_t print_nodes_state(enum node_states state, char *buf)
{ {
int n; int n;
n = nodelist_scnprintf(buf, PAGE_SIZE, node_states[state]); n = nodelist_scnprintf(buf, PAGE_SIZE-2, node_states[state]);
if (n > 0 && PAGE_SIZE > n + 1) { buf[n++] = '\n';
*(buf + n++) = '\n'; buf[n] = '\0';
*(buf + n++) = '\0';
}
return n; return n;
} }
......
...@@ -167,6 +167,14 @@ config GPIO_PXA ...@@ -167,6 +167,14 @@ config GPIO_PXA
help help
Say yes here to support the PXA GPIO device Say yes here to support the PXA GPIO device
config GPIO_STA2X11
bool "STA2x11/ConneXt GPIO support"
depends on MFD_STA2X11
select GENERIC_IRQ_CHIP
help
Say yes here to support the STA2x11/ConneXt GPIO device.
The GPIO module has 128 GPIO pins with alternate functions.
config GPIO_XILINX config GPIO_XILINX
bool "Xilinx GPIO support" bool "Xilinx GPIO support"
depends on PPC_OF || MICROBLAZE depends on PPC_OF || MICROBLAZE
...@@ -180,13 +188,13 @@ config GPIO_VR41XX ...@@ -180,13 +188,13 @@ config GPIO_VR41XX
Say yes here to support the NEC VR4100 series General-purpose I/O Uint Say yes here to support the NEC VR4100 series General-purpose I/O Uint
config GPIO_SCH config GPIO_SCH
tristate "Intel SCH/TunnelCreek GPIO" tristate "Intel SCH/TunnelCreek/Centerton GPIO"
depends on PCI && X86 depends on PCI && X86
select MFD_CORE select MFD_CORE
select LPC_SCH select LPC_SCH
help help
Say yes here to support GPIO interface on Intel Poulsbo SCH Say yes here to support GPIO interface on Intel Poulsbo SCH,
or Intel Tunnel Creek processor. Intel Tunnel Creek processor or Intel Centerton processor.
The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are The Intel SCH contains a total of 14 GPIO pins. Ten GPIOs are
powered by the core power rail and are turned off during sleep powered by the core power rail and are turned off during sleep
modes (S3 and higher). The remaining four GPIOs are powered by modes (S3 and higher). The remaining four GPIOs are powered by
...@@ -195,6 +203,22 @@ config GPIO_SCH ...@@ -195,6 +203,22 @@ config GPIO_SCH
system from the Suspend-to-RAM state. system from the Suspend-to-RAM state.
The Intel Tunnel Creek processor has 5 GPIOs powered by the The Intel Tunnel Creek processor has 5 GPIOs powered by the
core power rail and 9 from suspend power supply. core power rail and 9 from suspend power supply.
The Intel Centerton processor has a total of 30 GPIO pins.
Twenty-one are powered by the core power rail and 9 from the
suspend power supply.
config GPIO_ICH
tristate "Intel ICH GPIO"
depends on PCI && X86
select MFD_CORE
select LPC_ICH
help
Say yes here to support the GPIO functionality of a number of Intel
ICH-based chipsets. Currently supported devices: ICH6, ICH7, ICH8
ICH9, ICH10, Series 5/3400 (eg Ibex Peak), Series 6/C200 (eg
Cougar Point), NM10 (Tiger Point), and 3100 (Whitmore Lake).
If unsure, say N.
config GPIO_VX855 config GPIO_VX855
tristate "VIA VX855/VX875 GPIO" tristate "VIA VX855/VX875 GPIO"
......
...@@ -19,6 +19,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o ...@@ -19,6 +19,7 @@ obj-$(CONFIG_ARCH_DAVINCI) += gpio-davinci.o
obj-$(CONFIG_GPIO_EM) += gpio-em.o obj-$(CONFIG_GPIO_EM) += gpio-em.o
obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o obj-$(CONFIG_GPIO_EP93XX) += gpio-ep93xx.o
obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o obj-$(CONFIG_GPIO_GE_FPGA) += gpio-ge.o
obj-$(CONFIG_GPIO_ICH) += gpio-ich.o
obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o obj-$(CONFIG_GPIO_IT8761E) += gpio-it8761e.o
obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o obj-$(CONFIG_GPIO_JANZ_TTL) += gpio-janz-ttl.o
obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o obj-$(CONFIG_ARCH_KS8695) += gpio-ks8695.o
...@@ -51,6 +52,7 @@ obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o ...@@ -51,6 +52,7 @@ obj-$(CONFIG_PLAT_SAMSUNG) += gpio-samsung.o
obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o obj-$(CONFIG_ARCH_SA1100) += gpio-sa1100.o
obj-$(CONFIG_GPIO_SCH) += gpio-sch.o obj-$(CONFIG_GPIO_SCH) += gpio-sch.o
obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o obj-$(CONFIG_GPIO_SODAVILLE) += gpio-sodaville.o
obj-$(CONFIG_GPIO_STA2X11) += gpio-sta2x11.o
obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o obj-$(CONFIG_GPIO_STMPE) += gpio-stmpe.o
obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o obj-$(CONFIG_GPIO_SX150X) += gpio-sx150x.o
obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o obj-$(CONFIG_GPIO_TC3589X) += gpio-tc3589x.o
......
This diff is collapsed.
...@@ -232,6 +232,14 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev) ...@@ -232,6 +232,14 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev)
sch_gpio_resume.ngpio = 9; sch_gpio_resume.ngpio = 9;
break; break;
case PCI_DEVICE_ID_INTEL_CENTERTON_ILB:
sch_gpio_core.base = 0;
sch_gpio_core.ngpio = 21;
sch_gpio_resume.base = 21;
sch_gpio_resume.ngpio = 9;
break;
default: default:
return -ENODEV; return -ENODEV;
} }
......
This diff is collapsed.
...@@ -18,14 +18,27 @@ ...@@ -18,14 +18,27 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/mfd/tps65910.h> #include <linux/mfd/tps65910.h>
#include <linux/of_device.h>
struct tps65910_gpio {
struct gpio_chip gpio_chip;
struct tps65910 *tps65910;
};
static inline struct tps65910_gpio *to_tps65910_gpio(struct gpio_chip *chip)
{
return container_of(chip, struct tps65910_gpio, gpio_chip);
}
static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset)
{ {
struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
uint8_t val; struct tps65910 *tps65910 = tps65910_gpio->tps65910;
unsigned int val;
tps65910->read(tps65910, TPS65910_GPIO0 + offset, 1, &val); tps65910_reg_read(tps65910, TPS65910_GPIO0 + offset, &val);
if (val & GPIO_STS_MASK) if (val & GPIO_STS_MASK)
return 1; return 1;
...@@ -36,83 +49,170 @@ static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset) ...@@ -36,83 +49,170 @@ static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset)
static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset, static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset,
int value) int value)
{ {
struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
struct tps65910 *tps65910 = tps65910_gpio->tps65910;
if (value) if (value)
tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset, tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset,
GPIO_SET_MASK); GPIO_SET_MASK);
else else
tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset, tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset,
GPIO_SET_MASK); GPIO_SET_MASK);
} }
static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset, static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset,
int value) int value)
{ {
struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
struct tps65910 *tps65910 = tps65910_gpio->tps65910;
/* Set the initial value */ /* Set the initial value */
tps65910_gpio_set(gc, offset, value); tps65910_gpio_set(gc, offset, value);
return tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset, return tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset,
GPIO_CFG_MASK); GPIO_CFG_MASK);
} }
static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset) static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset)
{ {
struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio); struct tps65910_gpio *tps65910_gpio = to_tps65910_gpio(gc);
struct tps65910 *tps65910 = tps65910_gpio->tps65910;
return tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset, return tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset,
GPIO_CFG_MASK); GPIO_CFG_MASK);
} }
void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base) #ifdef CONFIG_OF
static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev,
struct tps65910 *tps65910, int chip_ngpio)
{ {
struct tps65910_board *tps65910_board = tps65910->of_plat_data;
unsigned int prop_array[TPS6591X_MAX_NUM_GPIO];
int ngpio = min(chip_ngpio, TPS6591X_MAX_NUM_GPIO);
int ret; int ret;
struct tps65910_board *board_data; int idx;
tps65910_board->gpio_base = -1;
ret = of_property_read_u32_array(tps65910->dev->of_node,
"ti,en-gpio-sleep", prop_array, ngpio);
if (ret < 0) {
dev_dbg(dev, "ti,en-gpio-sleep not specified\n");
return tps65910_board;
}
if (!gpio_base) for (idx = 0; idx < ngpio; idx++)
return; tps65910_board->en_gpio_sleep[idx] = (prop_array[idx] != 0);
tps65910->gpio.owner = THIS_MODULE; return tps65910_board;
tps65910->gpio.label = tps65910->i2c_client->name; }
tps65910->gpio.dev = tps65910->dev; #else
tps65910->gpio.base = gpio_base; static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev,
struct tps65910 *tps65910, int chip_ngpio)
{
return NULL;
}
#endif
static int __devinit tps65910_gpio_probe(struct platform_device *pdev)
{
struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);
struct tps65910_gpio *tps65910_gpio;
int ret;
int i;
tps65910_gpio = devm_kzalloc(&pdev->dev,
sizeof(*tps65910_gpio), GFP_KERNEL);
if (!tps65910_gpio) {
dev_err(&pdev->dev, "Could not allocate tps65910_gpio\n");
return -ENOMEM;
}
tps65910_gpio->tps65910 = tps65910;
tps65910_gpio->gpio_chip.owner = THIS_MODULE;
tps65910_gpio->gpio_chip.label = tps65910->i2c_client->name;
switch(tps65910_chip_id(tps65910)) { switch(tps65910_chip_id(tps65910)) {
case TPS65910: case TPS65910:
tps65910->gpio.ngpio = TPS65910_NUM_GPIO; tps65910_gpio->gpio_chip.ngpio = TPS65910_NUM_GPIO;
break; break;
case TPS65911: case TPS65911:
tps65910->gpio.ngpio = TPS65911_NUM_GPIO; tps65910_gpio->gpio_chip.ngpio = TPS65911_NUM_GPIO;
break; break;
default: default:
return; return -EINVAL;
}
tps65910_gpio->gpio_chip.can_sleep = 1;
tps65910_gpio->gpio_chip.direction_input = tps65910_gpio_input;
tps65910_gpio->gpio_chip.direction_output = tps65910_gpio_output;
tps65910_gpio->gpio_chip.set = tps65910_gpio_set;
tps65910_gpio->gpio_chip.get = tps65910_gpio_get;
tps65910_gpio->gpio_chip.dev = &pdev->dev;
if (pdata && pdata->gpio_base)
tps65910_gpio->gpio_chip.base = pdata->gpio_base;
else
tps65910_gpio->gpio_chip.base = -1;
if (!pdata && tps65910->dev->of_node)
pdata = tps65910_parse_dt_for_gpio(&pdev->dev, tps65910,
tps65910_gpio->gpio_chip.ngpio);
if (!pdata)
goto skip_init;
/* Configure sleep control for gpios if provided */
for (i = 0; i < tps65910_gpio->gpio_chip.ngpio; ++i) {
if (!pdata->en_gpio_sleep[i])
continue;
ret = tps65910_reg_set_bits(tps65910,
TPS65910_GPIO0 + i, GPIO_SLEEP_MASK);
if (ret < 0)
dev_warn(tps65910->dev,
"GPIO Sleep setting failed with err %d\n", ret);
} }
tps65910->gpio.can_sleep = 1;
skip_init:
tps65910->gpio.direction_input = tps65910_gpio_input; ret = gpiochip_add(&tps65910_gpio->gpio_chip);
tps65910->gpio.direction_output = tps65910_gpio_output; if (ret < 0) {
tps65910->gpio.set = tps65910_gpio_set; dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret);
tps65910->gpio.get = tps65910_gpio_get; return ret;
/* Configure sleep control for gpios */
board_data = dev_get_platdata(tps65910->dev);
if (board_data) {
int i;
for (i = 0; i < tps65910->gpio.ngpio; ++i) {
if (board_data->en_gpio_sleep[i]) {
ret = tps65910_set_bits(tps65910,
TPS65910_GPIO0 + i, GPIO_SLEEP_MASK);
if (ret < 0)
dev_warn(tps65910->dev,
"GPIO Sleep setting failed\n");
}
}
} }
ret = gpiochip_add(&tps65910->gpio); platform_set_drvdata(pdev, tps65910_gpio);
return ret;
}
static int __devexit tps65910_gpio_remove(struct platform_device *pdev)
{
struct tps65910_gpio *tps65910_gpio = platform_get_drvdata(pdev);
if (ret) return gpiochip_remove(&tps65910_gpio->gpio_chip);
dev_warn(tps65910->dev, "GPIO registration failed: %d\n", ret);
} }
static struct platform_driver tps65910_gpio_driver = {
.driver.name = "tps65910-gpio",
.driver.owner = THIS_MODULE,
.probe = tps65910_gpio_probe,
.remove = __devexit_p(tps65910_gpio_remove),
};
static int __init tps65910_gpio_init(void)
{
return platform_driver_register(&tps65910_gpio_driver);
}
subsys_initcall(tps65910_gpio_init);
static void __exit tps65910_gpio_exit(void)
{
platform_driver_unregister(&tps65910_gpio_driver);
}
module_exit(tps65910_gpio_exit);
MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
MODULE_AUTHOR("Jorge Eduardo Candelaria jedu@slimlogic.co.uk>");
MODULE_DESCRIPTION("GPIO interface for TPS65910/TPS6511 PMICs");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:tps65910-gpio");
...@@ -102,10 +102,8 @@ static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset) ...@@ -102,10 +102,8 @@ static int wm831x_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip); struct wm831x_gpio *wm831x_gpio = to_wm831x_gpio(chip);
struct wm831x *wm831x = wm831x_gpio->wm831x; struct wm831x *wm831x = wm831x_gpio->wm831x;
if (!wm831x->irq_base) return irq_create_mapping(wm831x->irq_domain,
return -EINVAL; WM831X_IRQ_GPIO_1 + offset);
return wm831x->irq_base + WM831X_IRQ_GPIO_1 + offset;
} }
static int wm831x_gpio_set_debounce(struct gpio_chip *chip, unsigned offset, static int wm831x_gpio_set_debounce(struct gpio_chip *chip, unsigned offset,
......
...@@ -73,7 +73,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev) ...@@ -73,7 +73,7 @@ static int __devinit wm831x_on_probe(struct platform_device *pdev)
{ {
struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent); struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
struct wm831x_on *wm831x_on; struct wm831x_on *wm831x_on;
int irq = platform_get_irq(pdev, 0); int irq = wm831x_irq(wm831x, platform_get_irq(pdev, 0));
int ret; int ret;
wm831x_on = kzalloc(sizeof(struct wm831x_on), GFP_KERNEL); wm831x_on = kzalloc(sizeof(struct wm831x_on), GFP_KERNEL);
......
...@@ -260,15 +260,16 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev) ...@@ -260,15 +260,16 @@ static __devinit int wm831x_ts_probe(struct platform_device *pdev)
* If we have a direct IRQ use it, otherwise use the interrupt * If we have a direct IRQ use it, otherwise use the interrupt
* from the WM831x IRQ controller. * from the WM831x IRQ controller.
*/ */
wm831x_ts->data_irq = wm831x_irq(wm831x,
platform_get_irq_byname(pdev,
"TCHDATA"));
if (pdata && pdata->data_irq) if (pdata && pdata->data_irq)
wm831x_ts->data_irq = pdata->data_irq; wm831x_ts->data_irq = pdata->data_irq;
else
wm831x_ts->data_irq = platform_get_irq_byname(pdev, "TCHDATA");
wm831x_ts->pd_irq = wm831x_irq(wm831x,
platform_get_irq_byname(pdev, "TCHPD"));
if (pdata && pdata->pd_irq) if (pdata && pdata->pd_irq)
wm831x_ts->pd_irq = pdata->pd_irq; wm831x_ts->pd_irq = pdata->pd_irq;
else
wm831x_ts->pd_irq = platform_get_irq_byname(pdev, "TCHPD");
if (pdata) if (pdata)
wm831x_ts->pressure = pdata->pressure; wm831x_ts->pressure = pdata->pressure;
......
...@@ -106,6 +106,19 @@ config UCB1400_CORE ...@@ -106,6 +106,19 @@ config UCB1400_CORE
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called ucb1400_core. module will be called ucb1400_core.
config MFD_LM3533
tristate "LM3533 Lighting Power chip"
depends on I2C
select MFD_CORE
select REGMAP_I2C
help
Say yes here to enable support for National Semiconductor / TI
LM3533 Lighting Power chips.
This driver provides common support for accessing the device;
additional drivers must be enabled in order to use the LED,
backlight or ambient-light-sensor functionality of the device.
config TPS6105X config TPS6105X
tristate "TPS61050/61052 Boost Converters" tristate "TPS61050/61052 Boost Converters"
depends on I2C depends on I2C
...@@ -177,8 +190,8 @@ config MFD_TPS65910 ...@@ -177,8 +190,8 @@ config MFD_TPS65910
bool "TPS65910 Power Management chip" bool "TPS65910 Power Management chip"
depends on I2C=y && GPIOLIB depends on I2C=y && GPIOLIB
select MFD_CORE select MFD_CORE
select GPIO_TPS65910
select REGMAP_I2C select REGMAP_I2C
select IRQ_DOMAIN
help help
if you say yes here you get support for the TPS65910 series of if you say yes here you get support for the TPS65910 series of
Power Management chips. Power Management chips.
...@@ -409,6 +422,19 @@ config PMIC_ADP5520 ...@@ -409,6 +422,19 @@ config PMIC_ADP5520
individual components like LCD backlight, LEDs, GPIOs and Kepad individual components like LCD backlight, LEDs, GPIOs and Kepad
under the corresponding menus. under the corresponding menus.
config MFD_MAX77693
bool "Maxim Semiconductor MAX77693 PMIC Support"
depends on I2C=y && GENERIC_HARDIRQS
select MFD_CORE
select REGMAP_I2C
help
Say yes here to support for Maxim Semiconductor MAX77693.
This is a companion Power Management IC with Flash, Haptic, Charger,
and MUIC(Micro USB Interface Controller) controls on chip.
This driver provides common support for accessing the device;
additional drivers must be enabled in order to use the functionality
of the device.
config MFD_MAX8925 config MFD_MAX8925
bool "Maxim Semiconductor MAX8925 PMIC Support" bool "Maxim Semiconductor MAX8925 PMIC Support"
depends on I2C=y && GENERIC_HARDIRQS depends on I2C=y && GENERIC_HARDIRQS
...@@ -454,9 +480,9 @@ config MFD_S5M_CORE ...@@ -454,9 +480,9 @@ config MFD_S5M_CORE
of the device of the device
config MFD_WM8400 config MFD_WM8400
tristate "Support Wolfson Microelectronics WM8400" bool "Support Wolfson Microelectronics WM8400"
select MFD_CORE select MFD_CORE
depends on I2C depends on I2C=y
select REGMAP_I2C select REGMAP_I2C
help help
Support for the Wolfson Microelecronics WM8400 PMIC and audio Support for the Wolfson Microelecronics WM8400 PMIC and audio
...@@ -473,6 +499,7 @@ config MFD_WM831X_I2C ...@@ -473,6 +499,7 @@ config MFD_WM831X_I2C
select MFD_CORE select MFD_CORE
select MFD_WM831X select MFD_WM831X
select REGMAP_I2C select REGMAP_I2C
select IRQ_DOMAIN
depends on I2C=y && GENERIC_HARDIRQS depends on I2C=y && GENERIC_HARDIRQS
help help
Support for the Wolfson Microelecronics WM831x and WM832x PMICs Support for the Wolfson Microelecronics WM831x and WM832x PMICs
...@@ -485,6 +512,7 @@ config MFD_WM831X_SPI ...@@ -485,6 +512,7 @@ config MFD_WM831X_SPI
select MFD_CORE select MFD_CORE
select MFD_WM831X select MFD_WM831X
select REGMAP_SPI select REGMAP_SPI
select IRQ_DOMAIN
depends on SPI_MASTER && GENERIC_HARDIRQS depends on SPI_MASTER && GENERIC_HARDIRQS
help help
Support for the Wolfson Microelecronics WM831x and WM832x PMICs Support for the Wolfson Microelecronics WM831x and WM832x PMICs
...@@ -597,17 +625,32 @@ config MFD_MC13783 ...@@ -597,17 +625,32 @@ config MFD_MC13783
tristate tristate
config MFD_MC13XXX config MFD_MC13XXX
tristate "Support Freescale MC13783 and MC13892" tristate
depends on SPI_MASTER depends on SPI_MASTER || I2C
select MFD_CORE select MFD_CORE
select MFD_MC13783 select MFD_MC13783
help help
Support for the Freescale (Atlas) PMIC and audio CODECs Enable support for the Freescale MC13783 and MC13892 PMICs.
MC13783 and MC13892. This driver provides common support for accessing the device,
This driver provides common support for accessing the device,
additional drivers must be enabled in order to use the additional drivers must be enabled in order to use the
functionality of the device. functionality of the device.
config MFD_MC13XXX_SPI
tristate "Freescale MC13783 and MC13892 SPI interface"
depends on SPI_MASTER
select REGMAP_SPI
select MFD_MC13XXX
help
Select this if your MC13xxx is connected via an SPI bus.
config MFD_MC13XXX_I2C
tristate "Freescale MC13892 I2C interface"
depends on I2C
select REGMAP_I2C
select MFD_MC13XXX
help
Select this if your MC13xxx is connected via an I2C bus.
config ABX500_CORE config ABX500_CORE
bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions" bool "ST-Ericsson ABX500 Mixed Signal Circuit register functions"
default y if ARCH_U300 || ARCH_U8500 default y if ARCH_U300 || ARCH_U8500
...@@ -651,7 +694,7 @@ config EZX_PCAP ...@@ -651,7 +694,7 @@ config EZX_PCAP
config AB8500_CORE config AB8500_CORE
bool "ST-Ericsson AB8500 Mixed Signal Power Management chip" bool "ST-Ericsson AB8500 Mixed Signal Power Management chip"
depends on GENERIC_HARDIRQS && ABX500_CORE depends on GENERIC_HARDIRQS && ABX500_CORE && MFD_DB8500_PRCMU
select MFD_CORE select MFD_CORE
help help
Select this option to enable access to AB8500 power management Select this option to enable access to AB8500 power management
...@@ -722,6 +765,16 @@ config LPC_SCH ...@@ -722,6 +765,16 @@ config LPC_SCH
LPC bridge function of the Intel SCH provides support for LPC bridge function of the Intel SCH provides support for
System Management Bus and General Purpose I/O. System Management Bus and General Purpose I/O.
config LPC_ICH
tristate "Intel ICH LPC"
depends on PCI
select MFD_CORE
help
The LPC bridge function of the Intel ICH provides support for
many functional units. This driver provides needed support for
other drivers to control these functions, currently GPIO and
watchdog.
config MFD_RDC321X config MFD_RDC321X
tristate "Support for RDC-R321x southbridge" tristate "Support for RDC-R321x southbridge"
select MFD_CORE select MFD_CORE
...@@ -854,6 +907,11 @@ config MFD_RC5T583 ...@@ -854,6 +907,11 @@ config MFD_RC5T583
Additional drivers must be enabled in order to use the Additional drivers must be enabled in order to use the
different functionality of the device. different functionality of the device.
config MFD_STA2X11
bool "STA2X11 multi function device support"
depends on STA2X11
select MFD_CORE
config MFD_ANATOP config MFD_ANATOP
bool "Support for Freescale i.MX on-chip ANATOP controller" bool "Support for Freescale i.MX on-chip ANATOP controller"
depends on SOC_IMX6Q depends on SOC_IMX6Q
......
...@@ -15,6 +15,7 @@ obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o ...@@ -15,6 +15,7 @@ obj-$(CONFIG_MFD_DAVINCI_VOICECODEC) += davinci_voicecodec.o
obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o obj-$(CONFIG_MFD_DM355EVM_MSP) += dm355evm_msp.o
obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o obj-$(CONFIG_MFD_TI_SSP) += ti-ssp.o
obj-$(CONFIG_MFD_STA2X11) += sta2x11-mfd.o
obj-$(CONFIG_MFD_STMPE) += stmpe.o obj-$(CONFIG_MFD_STMPE) += stmpe.o
obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o obj-$(CONFIG_STMPE_I2C) += stmpe-i2c.o
obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o obj-$(CONFIG_STMPE_SPI) += stmpe-spi.o
...@@ -54,6 +55,8 @@ obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o ...@@ -54,6 +55,8 @@ obj-$(CONFIG_TWL6030_PWM) += twl6030-pwm.o
obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o obj-$(CONFIG_TWL6040_CORE) += twl6040-core.o twl6040-irq.o
obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o obj-$(CONFIG_MFD_MC13XXX) += mc13xxx-core.o
obj-$(CONFIG_MFD_MC13XXX_SPI) += mc13xxx-spi.o
obj-$(CONFIG_MFD_MC13XXX_I2C) += mc13xxx-i2c.o
obj-$(CONFIG_MFD_CORE) += mfd-core.o obj-$(CONFIG_MFD_CORE) += mfd-core.o
...@@ -75,6 +78,7 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-core.o ...@@ -75,6 +78,7 @@ obj-$(CONFIG_PMIC_DA9052) += da9052-core.o
obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o obj-$(CONFIG_MFD_DA9052_SPI) += da9052-spi.o
obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o obj-$(CONFIG_MFD_DA9052_I2C) += da9052-i2c.o
obj-$(CONFIG_MFD_MAX77693) += max77693.o max77693-irq.o
max8925-objs := max8925-core.o max8925-i2c.o max8925-objs := max8925-core.o max8925-i2c.o
obj-$(CONFIG_MFD_MAX8925) += max8925.o obj-$(CONFIG_MFD_MAX8925) += max8925.o
obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o obj-$(CONFIG_MFD_MAX8997) += max8997.o max8997-irq.o
...@@ -87,15 +91,15 @@ obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o ...@@ -87,15 +91,15 @@ obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o
obj-$(CONFIG_ABX500_CORE) += abx500-core.o obj-$(CONFIG_ABX500_CORE) += abx500-core.o
obj-$(CONFIG_AB3100_CORE) += ab3100-core.o obj-$(CONFIG_AB3100_CORE) += ab3100-core.o
obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o
obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o obj-$(CONFIG_AB8500_DEBUG) += ab8500-debugfs.o
obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o obj-$(CONFIG_AB8500_GPADC) += ab8500-gpadc.o
obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_MFD_DB8500_PRCMU) += db8500-prcmu.o
# ab8500-i2c need to come after db8500-prcmu (which provides the channel) # ab8500-core need to come after db8500-prcmu (which provides the channel)
obj-$(CONFIG_AB8500_I2C_CORE) += ab8500-i2c.o obj-$(CONFIG_AB8500_CORE) += ab8500-core.o ab8500-sysctrl.o
obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o
obj-$(CONFIG_PMIC_ADP5520) += adp5520.o obj-$(CONFIG_PMIC_ADP5520) += adp5520.o
obj-$(CONFIG_LPC_SCH) += lpc_sch.o obj-$(CONFIG_LPC_SCH) += lpc_sch.o
obj-$(CONFIG_LPC_ICH) += lpc_ich.o
obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o obj-$(CONFIG_MFD_RDC321X) += rdc321x-southbridge.o
obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o obj-$(CONFIG_MFD_JANZ_CMODIO) += janz-cmodio.o
obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o obj-$(CONFIG_MFD_JZ4740_ADC) += jz4740-adc.o
......
This diff is collapsed.
...@@ -608,10 +608,16 @@ static int __devexit ab8500_debug_remove(struct platform_device *plf) ...@@ -608,10 +608,16 @@ static int __devexit ab8500_debug_remove(struct platform_device *plf)
return 0; return 0;
} }
static const struct of_device_id ab8500_debug_match[] = {
{ .compatible = "stericsson,ab8500-debug", },
{}
};
static struct platform_driver ab8500_debug_driver = { static struct platform_driver ab8500_debug_driver = {
.driver = { .driver = {
.name = "ab8500-debug", .name = "ab8500-debug",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = ab8500_debug_match,
}, },
.probe = ab8500_debug_probe, .probe = ab8500_debug_probe,
.remove = __devexit_p(ab8500_debug_remove) .remove = __devexit_p(ab8500_debug_remove)
......
...@@ -584,7 +584,7 @@ static int __devinit ab8500_gpadc_probe(struct platform_device *pdev) ...@@ -584,7 +584,7 @@ static int __devinit ab8500_gpadc_probe(struct platform_device *pdev)
gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END"); gpadc->irq = platform_get_irq_byname(pdev, "SW_CONV_END");
if (gpadc->irq < 0) { if (gpadc->irq < 0) {
dev_err(gpadc->dev, "failed to get platform irq-%d\n", dev_err(&pdev->dev, "failed to get platform irq-%d\n",
gpadc->irq); gpadc->irq);
ret = gpadc->irq; ret = gpadc->irq;
goto fail; goto fail;
...@@ -648,12 +648,18 @@ static int __devexit ab8500_gpadc_remove(struct platform_device *pdev) ...@@ -648,12 +648,18 @@ static int __devexit ab8500_gpadc_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct of_device_id ab8500_gpadc_match[] = {
{ .compatible = "stericsson,ab8500-gpadc", },
{}
};
static struct platform_driver ab8500_gpadc_driver = { static struct platform_driver ab8500_gpadc_driver = {
.probe = ab8500_gpadc_probe, .probe = ab8500_gpadc_probe,
.remove = __devexit_p(ab8500_gpadc_remove), .remove = __devexit_p(ab8500_gpadc_remove),
.driver = { .driver = {
.name = "ab8500-gpadc", .name = "ab8500-gpadc",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = ab8500_gpadc_match,
}, },
}; };
......
/*
* Copyright (C) ST-Ericsson SA 2010
* Author: Mattias Wallin <mattias.wallin@stericsson.com> for ST-Ericsson.
* License Terms: GNU General Public License v2
* This file was based on drivers/mfd/ab8500-spi.c
*/
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/mfd/abx500/ab8500.h>
#include <linux/mfd/dbx500-prcmu.h>
static int ab8500_i2c_write(struct ab8500 *ab8500, u16 addr, u8 data)
{
int ret;
ret = prcmu_abb_write((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1);
if (ret < 0)
dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
return ret;
}
static int ab8500_i2c_write_masked(struct ab8500 *ab8500, u16 addr, u8 mask,
u8 data)
{
int ret;
ret = prcmu_abb_write_masked((u8)(addr >> 8), (u8)(addr & 0xFF), &data,
&mask, 1);
if (ret < 0)
dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
return ret;
}
static int ab8500_i2c_read(struct ab8500 *ab8500, u16 addr)
{
int ret;
u8 data;
ret = prcmu_abb_read((u8)(addr >> 8), (u8)(addr & 0xFF), &data, 1);
if (ret < 0) {
dev_err(ab8500->dev, "prcmu i2c error %d\n", ret);
return ret;
}
return (int)data;
}
static int __devinit ab8500_i2c_probe(struct platform_device *plf)
{
const struct platform_device_id *platid = platform_get_device_id(plf);
struct ab8500 *ab8500;
struct resource *resource;
int ret;
ab8500 = kzalloc(sizeof *ab8500, GFP_KERNEL);
if (!ab8500)
return -ENOMEM;
ab8500->dev = &plf->dev;
resource = platform_get_resource(plf, IORESOURCE_IRQ, 0);
if (!resource) {
kfree(ab8500);
return -ENODEV;
}
ab8500->irq = resource->start;
ab8500->read = ab8500_i2c_read;
ab8500->write = ab8500_i2c_write;
ab8500->write_masked = ab8500_i2c_write_masked;
platform_set_drvdata(plf, ab8500);
ret = ab8500_init(ab8500, platid->driver_data);
if (ret)
kfree(ab8500);
return ret;
}
static int __devexit ab8500_i2c_remove(struct platform_device *plf)
{
struct ab8500 *ab8500 = platform_get_drvdata(plf);
ab8500_exit(ab8500);
kfree(ab8500);
return 0;
}
static const struct platform_device_id ab8500_id[] = {
{ "ab8500-i2c", AB8500_VERSION_AB8500 },
{ "ab8505-i2c", AB8500_VERSION_AB8505 },
{ "ab9540-i2c", AB8500_VERSION_AB9540 },
{ "ab8540-i2c", AB8500_VERSION_AB8540 },
{ }
};
static struct platform_driver ab8500_i2c_driver = {
.driver = {
.name = "ab8500-i2c",
.owner = THIS_MODULE,
},
.probe = ab8500_i2c_probe,
.remove = __devexit_p(ab8500_i2c_remove),
.id_table = ab8500_id,
};
static int __init ab8500_i2c_init(void)
{
return platform_driver_register(&ab8500_i2c_driver);
}
static void __exit ab8500_i2c_exit(void)
{
platform_driver_unregister(&ab8500_i2c_driver);
}
arch_initcall(ab8500_i2c_init);
module_exit(ab8500_i2c_exit);
MODULE_AUTHOR("Mattias WALLIN <mattias.wallin@stericsson.com");
MODULE_DESCRIPTION("AB8500 Core access via PRCMU I2C");
MODULE_LICENSE("GPL v2");
...@@ -61,10 +61,16 @@ static int __devexit ab8500_sysctrl_remove(struct platform_device *pdev) ...@@ -61,10 +61,16 @@ static int __devexit ab8500_sysctrl_remove(struct platform_device *pdev)
return 0; return 0;
} }
static const struct of_device_id ab8500_sysctrl_match[] = {
{ .compatible = "stericsson,ab8500-sysctrl", },
{}
};
static struct platform_driver ab8500_sysctrl_driver = { static struct platform_driver ab8500_sysctrl_driver = {
.driver = { .driver = {
.name = "ab8500-sysctrl", .name = "ab8500-sysctrl",
.owner = THIS_MODULE, .owner = THIS_MODULE,
.of_match_table = ab8500_sysctrl_match,
}, },
.probe = ab8500_sysctrl_probe, .probe = ab8500_sysctrl_probe,
.remove = __devexit_p(ab8500_sysctrl_remove), .remove = __devexit_p(ab8500_sysctrl_remove),
......
...@@ -41,39 +41,26 @@ ...@@ -41,39 +41,26 @@
#include <linux/of_address.h> #include <linux/of_address.h>
#include <linux/mfd/anatop.h> #include <linux/mfd/anatop.h>
u32 anatop_get_bits(struct anatop *adata, u32 addr, int bit_shift, u32 anatop_read_reg(struct anatop *adata, u32 addr)
int bit_width)
{ {
u32 val, mask; return readl(adata->ioreg + addr);
if (bit_width == 32)
mask = ~0;
else
mask = (1 << bit_width) - 1;
val = readl(adata->ioreg + addr);
val = (val >> bit_shift) & mask;
return val;
} }
EXPORT_SYMBOL_GPL(anatop_get_bits); EXPORT_SYMBOL_GPL(anatop_read_reg);
void anatop_set_bits(struct anatop *adata, u32 addr, int bit_shift, void anatop_write_reg(struct anatop *adata, u32 addr, u32 data, u32 mask)
int bit_width, u32 data)
{ {
u32 val, mask; u32 val;
if (bit_width == 32) data &= mask;
mask = ~0;
else
mask = (1 << bit_width) - 1;
spin_lock(&adata->reglock); spin_lock(&adata->reglock);
val = readl(adata->ioreg + addr) & ~(mask << bit_shift); val = readl(adata->ioreg + addr);
writel((data << bit_shift) | val, adata->ioreg + addr); val &= ~mask;
val |= data;
writel(val, adata->ioreg + addr);
spin_unlock(&adata->reglock); spin_unlock(&adata->reglock);
} }
EXPORT_SYMBOL_GPL(anatop_set_bits); EXPORT_SYMBOL_GPL(anatop_write_reg);
static const struct of_device_id of_anatop_match[] = { static const struct of_device_id of_anatop_match[] = {
{ .compatible = "fsl,imx6q-anatop", }, { .compatible = "fsl,imx6q-anatop", },
......
...@@ -353,12 +353,28 @@ static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type) ...@@ -353,12 +353,28 @@ static int asic3_gpio_irq_type(struct irq_data *data, unsigned int type)
return 0; return 0;
} }
static int asic3_gpio_irq_set_wake(struct irq_data *data, unsigned int on)
{
struct asic3 *asic = irq_data_get_irq_chip_data(data);
u32 bank, index;
u16 bit;
bank = asic3_irq_to_bank(asic, data->irq);
index = asic3_irq_to_index(asic, data->irq);
bit = 1<<index;
asic3_set_register(asic, bank + ASIC3_GPIO_SLEEP_MASK, bit, !on);
return 0;
}
static struct irq_chip asic3_gpio_irq_chip = { static struct irq_chip asic3_gpio_irq_chip = {
.name = "ASIC3-GPIO", .name = "ASIC3-GPIO",
.irq_ack = asic3_mask_gpio_irq, .irq_ack = asic3_mask_gpio_irq,
.irq_mask = asic3_mask_gpio_irq, .irq_mask = asic3_mask_gpio_irq,
.irq_unmask = asic3_unmask_gpio_irq, .irq_unmask = asic3_unmask_gpio_irq,
.irq_set_type = asic3_gpio_irq_type, .irq_set_type = asic3_gpio_irq_type,
.irq_set_wake = asic3_gpio_irq_set_wake,
}; };
static struct irq_chip asic3_irq_chip = { static struct irq_chip asic3_irq_chip = {
...@@ -529,7 +545,7 @@ static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset) ...@@ -529,7 +545,7 @@ static int asic3_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{ {
struct asic3 *asic = container_of(chip, struct asic3, gpio); struct asic3 *asic = container_of(chip, struct asic3, gpio);
return (offset < ASIC3_NUM_GPIOS) ? asic->irq_base + offset : -ENXIO; return asic->irq_base + offset;
} }
static __init int asic3_gpio_probe(struct platform_device *pdev, static __init int asic3_gpio_probe(struct platform_device *pdev,
...@@ -894,10 +910,13 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, ...@@ -894,10 +910,13 @@ static int __init asic3_mfd_probe(struct platform_device *pdev,
asic3_mmc_resources[0].start >>= asic->bus_shift; asic3_mmc_resources[0].start >>= asic->bus_shift;
asic3_mmc_resources[0].end >>= asic->bus_shift; asic3_mmc_resources[0].end >>= asic->bus_shift;
ret = mfd_add_devices(&pdev->dev, pdev->id, if (pdata->clock_rate) {
ds1wm_pdata.clock_rate = pdata->clock_rate;
ret = mfd_add_devices(&pdev->dev, pdev->id,
&asic3_cell_ds1wm, 1, mem, asic->irq_base); &asic3_cell_ds1wm, 1, mem, asic->irq_base);
if (ret < 0) if (ret < 0)
goto out; goto out;
}
if (mem_sdio && (irq >= 0)) { if (mem_sdio && (irq >= 0)) {
ret = mfd_add_devices(&pdev->dev, pdev->id, ret = mfd_add_devices(&pdev->dev, pdev->id,
...@@ -1000,6 +1019,9 @@ static int __init asic3_probe(struct platform_device *pdev) ...@@ -1000,6 +1019,9 @@ static int __init asic3_probe(struct platform_device *pdev)
asic3_mfd_probe(pdev, pdata, mem); asic3_mfd_probe(pdev, pdata, mem);
asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
(ASIC3_EXTCF_CF0_BUF_EN|ASIC3_EXTCF_CF0_PWAIT_EN), 1);
dev_info(asic->dev, "ASIC3 Core driver\n"); dev_info(asic->dev, "ASIC3 Core driver\n");
return 0; return 0;
...@@ -1021,6 +1043,9 @@ static int __devexit asic3_remove(struct platform_device *pdev) ...@@ -1021,6 +1043,9 @@ static int __devexit asic3_remove(struct platform_device *pdev)
int ret; int ret;
struct asic3 *asic = platform_get_drvdata(pdev); struct asic3 *asic = platform_get_drvdata(pdev);
asic3_set_register(asic, ASIC3_OFFSET(EXTCF, SELECT),
(ASIC3_EXTCF_CF0_BUF_EN|ASIC3_EXTCF_CF0_PWAIT_EN), 0);
asic3_mfd_remove(pdev); asic3_mfd_remove(pdev);
ret = asic3_gpio_remove(pdev); ret = asic3_gpio_remove(pdev);
......
...@@ -186,18 +186,7 @@ static struct pci_driver cs5535_mfd_driver = { ...@@ -186,18 +186,7 @@ static struct pci_driver cs5535_mfd_driver = {
.remove = __devexit_p(cs5535_mfd_remove), .remove = __devexit_p(cs5535_mfd_remove),
}; };
static int __init cs5535_mfd_init(void) module_pci_driver(cs5535_mfd_driver);
{
return pci_register_driver(&cs5535_mfd_driver);
}
static void __exit cs5535_mfd_exit(void)
{
pci_unregister_driver(&cs5535_mfd_driver);
}
module_init(cs5535_mfd_init);
module_exit(cs5535_mfd_exit);
MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>");
MODULE_DESCRIPTION("MFD driver for CS5535/CS5536 southbridge's ISA PCI device"); MODULE_DESCRIPTION("MFD driver for CS5535/CS5536 southbridge's ISA PCI device");
......
...@@ -318,6 +318,135 @@ static bool da9052_reg_volatile(struct device *dev, unsigned int reg) ...@@ -318,6 +318,135 @@ static bool da9052_reg_volatile(struct device *dev, unsigned int reg)
} }
} }
/*
* TBAT look-up table is computed from the R90 reg (8 bit register)
* reading as below. The battery temperature is in milliCentigrade
* TBAT = (1/(t1+1/298) - 273) * 1000 mC
* where t1 = (1/B)* ln(( ADCval * 2.5)/(R25*ITBAT*255))
* Default values are R25 = 10e3, B = 3380, ITBAT = 50e-6
* Example:
* R25=10E3, B=3380, ITBAT=50e-6, ADCVAL=62d calculates
* TBAT = 20015 mili degrees Centrigrade
*
*/
static const int32_t tbat_lookup[255] = {
183258, 144221, 124334, 111336, 101826, 94397, 88343, 83257,
78889, 75071, 71688, 68656, 65914, 63414, 61120, 59001,
570366, 55204, 53490, 51881, 50364, 48931, 47574, 46285,
45059, 43889, 42772, 41703, 40678, 39694, 38748, 37838,
36961, 36115, 35297, 34507, 33743, 33002, 32284, 31588,
30911, 30254, 29615, 28994, 28389, 27799, 27225, 26664,
26117, 25584, 25062, 24553, 24054, 23567, 23091, 22624,
22167, 21719, 21281, 20851, 20429, 20015, 19610, 19211,
18820, 18436, 18058, 17688, 17323, 16965, 16612, 16266,
15925, 15589, 15259, 14933, 14613, 14298, 13987, 13681,
13379, 13082, 12788, 12499, 12214, 11933, 11655, 11382,
11112, 10845, 10582, 10322, 10066, 9812, 9562, 9315,
9071, 8830, 8591, 8356, 8123, 7893, 7665, 7440,
7218, 6998, 6780, 6565, 6352, 6141, 5933, 5726,
5522, 5320, 5120, 4922, 4726, 4532, 4340, 4149,
3961, 3774, 3589, 3406, 3225, 3045, 2867, 2690,
2516, 2342, 2170, 2000, 1831, 1664, 1498, 1334,
1171, 1009, 849, 690, 532, 376, 221, 67,
-84, -236, -386, -535, -683, -830, -975, -1119,
-1263, -1405, -1546, -1686, -1825, -1964, -2101, -2237,
-2372, -2506, -2639, -2771, -2902, -3033, -3162, -3291,
-3418, -3545, -3671, -3796, -3920, -4044, -4166, -4288,
-4409, -4529, -4649, -4767, -4885, -5002, -5119, -5235,
-5349, -5464, -5577, -5690, -5802, -5913, -6024, -6134,
-6244, -6352, -6461, -6568, -6675, -6781, -6887, -6992,
-7096, -7200, -7303, -7406, -7508, -7609, -7710, -7810,
-7910, -8009, -8108, -8206, -8304, -8401, -8497, -8593,
-8689, -8784, -8878, -8972, -9066, -9159, -9251, -9343,
-9435, -9526, -9617, -9707, -9796, -9886, -9975, -10063,
-10151, -10238, -10325, -10412, -10839, -10923, -11007, -11090,
-11173, -11256, -11338, -11420, -11501, -11583, -11663, -11744,
-11823, -11903, -11982
};
static const u8 chan_mux[DA9052_ADC_VBBAT + 1] = {
[DA9052_ADC_VDDOUT] = DA9052_ADC_MAN_MUXSEL_VDDOUT,
[DA9052_ADC_ICH] = DA9052_ADC_MAN_MUXSEL_ICH,
[DA9052_ADC_TBAT] = DA9052_ADC_MAN_MUXSEL_TBAT,
[DA9052_ADC_VBAT] = DA9052_ADC_MAN_MUXSEL_VBAT,
[DA9052_ADC_IN4] = DA9052_ADC_MAN_MUXSEL_AD4,
[DA9052_ADC_IN5] = DA9052_ADC_MAN_MUXSEL_AD5,
[DA9052_ADC_IN6] = DA9052_ADC_MAN_MUXSEL_AD6,
[DA9052_ADC_VBBAT] = DA9052_ADC_MAN_MUXSEL_VBBAT
};
int da9052_adc_manual_read(struct da9052 *da9052, unsigned char channel)
{
int ret;
unsigned short calc_data;
unsigned short data;
unsigned char mux_sel;
if (channel > DA9052_ADC_VBBAT)
return -EINVAL;
mutex_lock(&da9052->auxadc_lock);
/* Channel gets activated on enabling the Conversion bit */
mux_sel = chan_mux[channel] | DA9052_ADC_MAN_MAN_CONV;
ret = da9052_reg_write(da9052, DA9052_ADC_MAN_REG, mux_sel);
if (ret < 0)
goto err;
/* Wait for an interrupt */
if (!wait_for_completion_timeout(&da9052->done,
msecs_to_jiffies(500))) {
dev_err(da9052->dev,
"timeout waiting for ADC conversion interrupt\n");
ret = -ETIMEDOUT;
goto err;
}
ret = da9052_reg_read(da9052, DA9052_ADC_RES_H_REG);
if (ret < 0)
goto err;
calc_data = (unsigned short)ret;
data = calc_data << 2;
ret = da9052_reg_read(da9052, DA9052_ADC_RES_L_REG);
if (ret < 0)
goto err;
calc_data = (unsigned short)(ret & DA9052_ADC_RES_LSB);
data |= calc_data;
ret = data;
err:
mutex_unlock(&da9052->auxadc_lock);
return ret;
}
EXPORT_SYMBOL_GPL(da9052_adc_manual_read);
static irqreturn_t da9052_auxadc_irq(int irq, void *irq_data)
{
struct da9052 *da9052 = irq_data;
complete(&da9052->done);
return IRQ_HANDLED;
}
int da9052_adc_read_temp(struct da9052 *da9052)
{
int tbat;
tbat = da9052_reg_read(da9052, DA9052_TBAT_RES_REG);
if (tbat <= 0)
return tbat;
/* ARRAY_SIZE check is not needed since TBAT is a 8-bit register */
return tbat_lookup[tbat - 1];
}
EXPORT_SYMBOL_GPL(da9052_adc_read_temp);
static struct resource da9052_rtc_resource = { static struct resource da9052_rtc_resource = {
.name = "ALM", .name = "ALM",
.start = DA9052_IRQ_ALARM, .start = DA9052_IRQ_ALARM,
...@@ -646,6 +775,9 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) ...@@ -646,6 +775,9 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
struct irq_desc *desc; struct irq_desc *desc;
int ret; int ret;
mutex_init(&da9052->auxadc_lock);
init_completion(&da9052->done);
if (pdata && pdata->init != NULL) if (pdata && pdata->init != NULL)
pdata->init(da9052); pdata->init(da9052);
...@@ -665,6 +797,12 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) ...@@ -665,6 +797,12 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
da9052->irq_base = regmap_irq_chip_get_base(da9052->irq_data); da9052->irq_base = regmap_irq_chip_get_base(da9052->irq_data);
ret = request_threaded_irq(DA9052_IRQ_ADC_EOM, NULL, da9052_auxadc_irq,
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
"adc irq", da9052);
if (ret != 0)
dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret);
ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info, ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info,
ARRAY_SIZE(da9052_subdev_info), NULL, 0); ARRAY_SIZE(da9052_subdev_info), NULL, 0);
if (ret) if (ret)
...@@ -673,6 +811,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) ...@@ -673,6 +811,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
return 0; return 0;
err: err:
free_irq(DA9052_IRQ_ADC_EOM, da9052);
mfd_remove_devices(da9052->dev); mfd_remove_devices(da9052->dev);
regmap_err: regmap_err:
return ret; return ret;
...@@ -680,6 +819,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id) ...@@ -680,6 +819,7 @@ int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
void da9052_device_exit(struct da9052 *da9052) void da9052_device_exit(struct da9052 *da9052)
{ {
free_irq(DA9052_IRQ_ADC_EOM, da9052);
regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data); regmap_del_irq_chip(da9052->chip_irq, da9052->irq_data);
mfd_remove_devices(da9052->dev); mfd_remove_devices(da9052->dev);
} }
......
...@@ -22,6 +22,11 @@ ...@@ -22,6 +22,11 @@
#include <linux/mfd/da9052/da9052.h> #include <linux/mfd/da9052/da9052.h>
#include <linux/mfd/da9052/reg.h> #include <linux/mfd/da9052/reg.h>
#ifdef CONFIG_OF
#include <linux/of.h>
#include <linux/of_device.h>
#endif
static int da9052_i2c_enable_multiwrite(struct da9052 *da9052) static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
{ {
int reg_val, ret; int reg_val, ret;
...@@ -41,13 +46,31 @@ static int da9052_i2c_enable_multiwrite(struct da9052 *da9052) ...@@ -41,13 +46,31 @@ static int da9052_i2c_enable_multiwrite(struct da9052 *da9052)
return 0; return 0;
} }
static struct i2c_device_id da9052_i2c_id[] = {
{"da9052", DA9052},
{"da9053-aa", DA9053_AA},
{"da9053-ba", DA9053_BA},
{"da9053-bb", DA9053_BB},
{}
};
#ifdef CONFIG_OF
static const struct of_device_id dialog_dt_ids[] = {
{ .compatible = "dlg,da9052", .data = &da9052_i2c_id[0] },
{ .compatible = "dlg,da9053-aa", .data = &da9052_i2c_id[1] },
{ .compatible = "dlg,da9053-ab", .data = &da9052_i2c_id[2] },
{ .compatible = "dlg,da9053-bb", .data = &da9052_i2c_id[3] },
{ /* sentinel */ }
};
#endif
static int __devinit da9052_i2c_probe(struct i2c_client *client, static int __devinit da9052_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct da9052 *da9052; struct da9052 *da9052;
int ret; int ret;
da9052 = kzalloc(sizeof(struct da9052), GFP_KERNEL); da9052 = devm_kzalloc(&client->dev, sizeof(struct da9052), GFP_KERNEL);
if (!da9052) if (!da9052)
return -ENOMEM; return -ENOMEM;
...@@ -55,8 +78,7 @@ static int __devinit da9052_i2c_probe(struct i2c_client *client, ...@@ -55,8 +78,7 @@ static int __devinit da9052_i2c_probe(struct i2c_client *client,
I2C_FUNC_SMBUS_BYTE_DATA)) { I2C_FUNC_SMBUS_BYTE_DATA)) {
dev_info(&client->dev, "Error in %s:i2c_check_functionality\n", dev_info(&client->dev, "Error in %s:i2c_check_functionality\n",
__func__); __func__);
ret = -ENODEV; return -ENODEV;
goto err;
} }
da9052->dev = &client->dev; da9052->dev = &client->dev;
...@@ -64,29 +86,39 @@ static int __devinit da9052_i2c_probe(struct i2c_client *client, ...@@ -64,29 +86,39 @@ static int __devinit da9052_i2c_probe(struct i2c_client *client,
i2c_set_clientdata(client, da9052); i2c_set_clientdata(client, da9052);
da9052->regmap = regmap_init_i2c(client, &da9052_regmap_config); da9052->regmap = devm_regmap_init_i2c(client, &da9052_regmap_config);
if (IS_ERR(da9052->regmap)) { if (IS_ERR(da9052->regmap)) {
ret = PTR_ERR(da9052->regmap); ret = PTR_ERR(da9052->regmap);
dev_err(&client->dev, "Failed to allocate register map: %d\n", dev_err(&client->dev, "Failed to allocate register map: %d\n",
ret); ret);
goto err; return ret;
} }
ret = da9052_i2c_enable_multiwrite(da9052); ret = da9052_i2c_enable_multiwrite(da9052);
if (ret < 0) if (ret < 0)
goto err_regmap; return ret;
#ifdef CONFIG_OF
if (!id) {
struct device_node *np = client->dev.of_node;
const struct of_device_id *deviceid;
deviceid = of_match_node(dialog_dt_ids, np);
id = (const struct i2c_device_id *)deviceid->data;
}
#endif
if (!id) {
ret = -ENODEV;
dev_err(&client->dev, "id is null.\n");
return ret;
}
ret = da9052_device_init(da9052, id->driver_data); ret = da9052_device_init(da9052, id->driver_data);
if (ret != 0) if (ret != 0)
goto err_regmap; return ret;
return 0; return 0;
err_regmap:
regmap_exit(da9052->regmap);
err:
kfree(da9052);
return ret;
} }
static int __devexit da9052_i2c_remove(struct i2c_client *client) static int __devexit da9052_i2c_remove(struct i2c_client *client)
...@@ -94,20 +126,9 @@ static int __devexit da9052_i2c_remove(struct i2c_client *client) ...@@ -94,20 +126,9 @@ static int __devexit da9052_i2c_remove(struct i2c_client *client)
struct da9052 *da9052 = i2c_get_clientdata(client); struct da9052 *da9052 = i2c_get_clientdata(client);
da9052_device_exit(da9052); da9052_device_exit(da9052);
regmap_exit(da9052->regmap);
kfree(da9052);
return 0; return 0;
} }
static struct i2c_device_id da9052_i2c_id[] = {
{"da9052", DA9052},
{"da9053-aa", DA9053_AA},
{"da9053-ba", DA9053_BA},
{"da9053-bb", DA9053_BB},
{}
};
static struct i2c_driver da9052_i2c_driver = { static struct i2c_driver da9052_i2c_driver = {
.probe = da9052_i2c_probe, .probe = da9052_i2c_probe,
.remove = __devexit_p(da9052_i2c_remove), .remove = __devexit_p(da9052_i2c_remove),
...@@ -115,6 +136,9 @@ static struct i2c_driver da9052_i2c_driver = { ...@@ -115,6 +136,9 @@ static struct i2c_driver da9052_i2c_driver = {
.driver = { .driver = {
.name = "da9052", .name = "da9052",
.owner = THIS_MODULE, .owner = THIS_MODULE,
#ifdef CONFIG_OF
.of_match_table = dialog_dt_ids,
#endif
}, },
}; };
......
...@@ -25,8 +25,9 @@ static int __devinit da9052_spi_probe(struct spi_device *spi) ...@@ -25,8 +25,9 @@ static int __devinit da9052_spi_probe(struct spi_device *spi)
{ {
int ret; int ret;
const struct spi_device_id *id = spi_get_device_id(spi); const struct spi_device_id *id = spi_get_device_id(spi);
struct da9052 *da9052 = kzalloc(sizeof(struct da9052), GFP_KERNEL); struct da9052 *da9052;
da9052 = devm_kzalloc(&spi->dev, sizeof(struct da9052), GFP_KERNEL);
if (!da9052) if (!da9052)
return -ENOMEM; return -ENOMEM;
...@@ -42,25 +43,19 @@ static int __devinit da9052_spi_probe(struct spi_device *spi) ...@@ -42,25 +43,19 @@ static int __devinit da9052_spi_probe(struct spi_device *spi)
da9052_regmap_config.read_flag_mask = 1; da9052_regmap_config.read_flag_mask = 1;
da9052_regmap_config.write_flag_mask = 0; da9052_regmap_config.write_flag_mask = 0;
da9052->regmap = regmap_init_spi(spi, &da9052_regmap_config); da9052->regmap = devm_regmap_init_spi(spi, &da9052_regmap_config);
if (IS_ERR(da9052->regmap)) { if (IS_ERR(da9052->regmap)) {
ret = PTR_ERR(da9052->regmap); ret = PTR_ERR(da9052->regmap);
dev_err(&spi->dev, "Failed to allocate register map: %d\n", dev_err(&spi->dev, "Failed to allocate register map: %d\n",
ret); ret);
goto err; return ret;
} }
ret = da9052_device_init(da9052, id->driver_data); ret = da9052_device_init(da9052, id->driver_data);
if (ret != 0) if (ret != 0)
goto err_regmap; return ret;
return 0; return 0;
err_regmap:
regmap_exit(da9052->regmap);
err:
kfree(da9052);
return ret;
} }
static int __devexit da9052_spi_remove(struct spi_device *spi) static int __devexit da9052_spi_remove(struct spi_device *spi)
...@@ -68,9 +63,6 @@ static int __devexit da9052_spi_remove(struct spi_device *spi) ...@@ -68,9 +63,6 @@ static int __devexit da9052_spi_remove(struct spi_device *spi)
struct da9052 *da9052 = dev_get_drvdata(&spi->dev); struct da9052 *da9052 = dev_get_drvdata(&spi->dev);
da9052_device_exit(da9052); da9052_device_exit(da9052);
regmap_exit(da9052->regmap);
kfree(da9052);
return 0; return 0;
} }
...@@ -88,7 +80,6 @@ static struct spi_driver da9052_spi_driver = { ...@@ -88,7 +80,6 @@ static struct spi_driver da9052_spi_driver = {
.id_table = da9052_spi_id, .id_table = da9052_spi_id,
.driver = { .driver = {
.name = "da9052", .name = "da9052",
.bus = &spi_bus_type,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
}; };
......
...@@ -2720,6 +2720,7 @@ static struct regulator_consumer_supply db8500_vape_consumers[] = { ...@@ -2720,6 +2720,7 @@ static struct regulator_consumer_supply db8500_vape_consumers[] = {
REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"), REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"),
REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"), REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"),
REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"), REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"),
REGULATOR_SUPPLY("v-i2c", "nmk-i2c.4"),
/* "v-mmc" changed to "vcore" in the mainline kernel */ /* "v-mmc" changed to "vcore" in the mainline kernel */
REGULATOR_SUPPLY("vcore", "sdi0"), REGULATOR_SUPPLY("vcore", "sdi0"),
REGULATOR_SUPPLY("vcore", "sdi1"), REGULATOR_SUPPLY("vcore", "sdi1"),
...@@ -2958,9 +2959,10 @@ static struct mfd_cell db8500_prcmu_devs[] = { ...@@ -2958,9 +2959,10 @@ static struct mfd_cell db8500_prcmu_devs[] = {
* prcmu_fw_init - arch init call for the Linux PRCMU fw init logic * prcmu_fw_init - arch init call for the Linux PRCMU fw init logic
* *
*/ */
static int __init db8500_prcmu_probe(struct platform_device *pdev) static int __devinit db8500_prcmu_probe(struct platform_device *pdev)
{ {
int err = 0; struct device_node *np = pdev->dev.of_node;
int irq = 0, err = 0;
if (ux500_is_svp()) if (ux500_is_svp())
return -ENODEV; return -ENODEV;
...@@ -2970,8 +2972,14 @@ static int __init db8500_prcmu_probe(struct platform_device *pdev) ...@@ -2970,8 +2972,14 @@ static int __init db8500_prcmu_probe(struct platform_device *pdev)
/* Clean up the mailbox interrupts after pre-kernel code. */ /* Clean up the mailbox interrupts after pre-kernel code. */
writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR);
err = request_threaded_irq(IRQ_DB8500_PRCMU1, prcmu_irq_handler, if (np)
prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); irq = platform_get_irq(pdev, 0);
if (!np || irq <= 0)
irq = IRQ_DB8500_PRCMU1;
err = request_threaded_irq(irq, prcmu_irq_handler,
prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL);
if (err < 0) { if (err < 0) {
pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n"); pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n");
err = -EBUSY; err = -EBUSY;
...@@ -2981,14 +2989,16 @@ static int __init db8500_prcmu_probe(struct platform_device *pdev) ...@@ -2981,14 +2989,16 @@ static int __init db8500_prcmu_probe(struct platform_device *pdev)
if (cpu_is_u8500v20_or_later()) if (cpu_is_u8500v20_or_later())
prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs, if (!np) {
ARRAY_SIZE(db8500_prcmu_devs), NULL, err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs,
0); ARRAY_SIZE(db8500_prcmu_devs), NULL, 0);
if (err) {
pr_err("prcmu: Failed to add subdevices\n");
return err;
}
}
if (err) pr_info("DB8500 PRCMU initialized\n");
pr_err("prcmu: Failed to add subdevices\n");
else
pr_info("DB8500 PRCMU initialized\n");
no_irq_return: no_irq_return:
return err; return err;
...@@ -2999,11 +3009,12 @@ static struct platform_driver db8500_prcmu_driver = { ...@@ -2999,11 +3009,12 @@ static struct platform_driver db8500_prcmu_driver = {
.name = "db8500-prcmu", .name = "db8500-prcmu",
.owner = THIS_MODULE, .owner = THIS_MODULE,
}, },
.probe = db8500_prcmu_probe,
}; };
static int __init db8500_prcmu_init(void) static int __init db8500_prcmu_init(void)
{ {
return platform_driver_probe(&db8500_prcmu_driver, db8500_prcmu_probe); return platform_driver_register(&db8500_prcmu_driver);
} }
arch_initcall(db8500_prcmu_init); arch_initcall(db8500_prcmu_init);
......
...@@ -406,7 +406,7 @@ static int __devinit intel_msic_probe(struct platform_device *pdev) ...@@ -406,7 +406,7 @@ static int __devinit intel_msic_probe(struct platform_device *pdev)
return -ENXIO; return -ENXIO;
} }
msic = kzalloc(sizeof(*msic), GFP_KERNEL); msic = devm_kzalloc(&pdev->dev, sizeof(*msic), GFP_KERNEL);
if (!msic) if (!msic)
return -ENOMEM; return -ENOMEM;
...@@ -421,21 +421,13 @@ static int __devinit intel_msic_probe(struct platform_device *pdev) ...@@ -421,21 +421,13 @@ static int __devinit intel_msic_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) { if (!res) {
dev_err(&pdev->dev, "failed to get SRAM iomem resource\n"); dev_err(&pdev->dev, "failed to get SRAM iomem resource\n");
ret = -ENODEV; return -ENODEV;
goto fail_free_msic;
} }
res = request_mem_region(res->start, resource_size(res), pdev->name); msic->irq_base = devm_request_and_ioremap(&pdev->dev, res);
if (!res) {
ret = -EBUSY;
goto fail_free_msic;
}
msic->irq_base = ioremap_nocache(res->start, resource_size(res));
if (!msic->irq_base) { if (!msic->irq_base) {
dev_err(&pdev->dev, "failed to map SRAM memory\n"); dev_err(&pdev->dev, "failed to map SRAM memory\n");
ret = -ENOMEM; return -ENOMEM;
goto fail_release_region;
} }
platform_set_drvdata(pdev, msic); platform_set_drvdata(pdev, msic);
...@@ -443,7 +435,7 @@ static int __devinit intel_msic_probe(struct platform_device *pdev) ...@@ -443,7 +435,7 @@ static int __devinit intel_msic_probe(struct platform_device *pdev)
ret = intel_msic_init_devices(msic); ret = intel_msic_init_devices(msic);
if (ret) { if (ret) {
dev_err(&pdev->dev, "failed to initialize MSIC devices\n"); dev_err(&pdev->dev, "failed to initialize MSIC devices\n");
goto fail_unmap_mem; return ret;
} }
dev_info(&pdev->dev, "Intel MSIC version %c%d (vendor %#x)\n", dev_info(&pdev->dev, "Intel MSIC version %c%d (vendor %#x)\n",
...@@ -451,27 +443,14 @@ static int __devinit intel_msic_probe(struct platform_device *pdev) ...@@ -451,27 +443,14 @@ static int __devinit intel_msic_probe(struct platform_device *pdev)
msic->vendor); msic->vendor);
return 0; return 0;
fail_unmap_mem:
iounmap(msic->irq_base);
fail_release_region:
release_mem_region(res->start, resource_size(res));
fail_free_msic:
kfree(msic);
return ret;
} }
static int __devexit intel_msic_remove(struct platform_device *pdev) static int __devexit intel_msic_remove(struct platform_device *pdev)
{ {
struct intel_msic *msic = platform_get_drvdata(pdev); struct intel_msic *msic = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
intel_msic_remove_devices(msic); intel_msic_remove_devices(msic);
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
iounmap(msic->irq_base);
release_mem_region(res->start, resource_size(res));
kfree(msic);
return 0; return 0;
} }
......
...@@ -283,23 +283,8 @@ static struct pci_driver cmodio_pci_driver = { ...@@ -283,23 +283,8 @@ static struct pci_driver cmodio_pci_driver = {
.remove = __devexit_p(cmodio_pci_remove), .remove = __devexit_p(cmodio_pci_remove),
}; };
/* module_pci_driver(cmodio_pci_driver);
* Module Init / Exit
*/
static int __init cmodio_init(void)
{
return pci_register_driver(&cmodio_pci_driver);
}
static void __exit cmodio_exit(void)
{
pci_unregister_driver(&cmodio_pci_driver);
}
MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>"); MODULE_AUTHOR("Ira W. Snyder <iws@ovro.caltech.edu>");
MODULE_DESCRIPTION("Janz CMOD-IO PCI MODULbus Carrier Board Driver"); MODULE_DESCRIPTION("Janz CMOD-IO PCI MODULbus Carrier Board Driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
module_init(cmodio_init);
module_exit(cmodio_exit);
This diff is collapsed.
/*
* lm3533-ctrlbank.c -- LM3533 Generic Control Bank interface
*
* Copyright (C) 2011-2012 Texas Instruments
*
* Author: Johan Hovold <jhovold@gmail.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/mfd/lm3533.h>
#define LM3533_MAX_CURRENT_MIN 5000
#define LM3533_MAX_CURRENT_MAX 29800
#define LM3533_MAX_CURRENT_STEP 800
#define LM3533_BRIGHTNESS_MAX 255
#define LM3533_PWM_MAX 0x3f
#define LM3533_REG_PWM_BASE 0x14
#define LM3533_REG_MAX_CURRENT_BASE 0x1f
#define LM3533_REG_CTRLBANK_ENABLE 0x27
#define LM3533_REG_BRIGHTNESS_BASE 0x40
static inline u8 lm3533_ctrlbank_get_reg(struct lm3533_ctrlbank *cb, u8 base)
{
return base + cb->id;
}
int lm3533_ctrlbank_enable(struct lm3533_ctrlbank *cb)
{
u8 mask;
int ret;
dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id);
mask = 1 << cb->id;
ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE,
mask, mask);
if (ret)
dev_err(cb->dev, "failed to enable ctrlbank %d\n", cb->id);
return ret;
}
EXPORT_SYMBOL_GPL(lm3533_ctrlbank_enable);
int lm3533_ctrlbank_disable(struct lm3533_ctrlbank *cb)
{
u8 mask;
int ret;
dev_dbg(cb->dev, "%s - %d\n", __func__, cb->id);
mask = 1 << cb->id;
ret = lm3533_update(cb->lm3533, LM3533_REG_CTRLBANK_ENABLE, 0, mask);
if (ret)
dev_err(cb->dev, "failed to disable ctrlbank %d\n", cb->id);
return ret;
}
EXPORT_SYMBOL_GPL(lm3533_ctrlbank_disable);
/*
* Full-scale current.
*
* imax 5000 - 29800 uA (800 uA step)
*/
int lm3533_ctrlbank_set_max_current(struct lm3533_ctrlbank *cb, u16 imax)
{
u8 reg;
u8 val;
int ret;
if (imax < LM3533_MAX_CURRENT_MIN || imax > LM3533_MAX_CURRENT_MAX)
return -EINVAL;
val = (imax - LM3533_MAX_CURRENT_MIN) / LM3533_MAX_CURRENT_STEP;
reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_MAX_CURRENT_BASE);
ret = lm3533_write(cb->lm3533, reg, val);
if (ret)
dev_err(cb->dev, "failed to set max current\n");
return ret;
}
EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_max_current);
#define lm3533_ctrlbank_set(_name, _NAME) \
int lm3533_ctrlbank_set_##_name(struct lm3533_ctrlbank *cb, u8 val) \
{ \
u8 reg; \
int ret; \
\
if (val > LM3533_##_NAME##_MAX) \
return -EINVAL; \
\
reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_##_NAME##_BASE); \
ret = lm3533_write(cb->lm3533, reg, val); \
if (ret) \
dev_err(cb->dev, "failed to set " #_name "\n"); \
\
return ret; \
} \
EXPORT_SYMBOL_GPL(lm3533_ctrlbank_set_##_name);
#define lm3533_ctrlbank_get(_name, _NAME) \
int lm3533_ctrlbank_get_##_name(struct lm3533_ctrlbank *cb, u8 *val) \
{ \
u8 reg; \
int ret; \
\
reg = lm3533_ctrlbank_get_reg(cb, LM3533_REG_##_NAME##_BASE); \
ret = lm3533_read(cb->lm3533, reg, val); \
if (ret) \
dev_err(cb->dev, "failed to get " #_name "\n"); \
\
return ret; \
} \
EXPORT_SYMBOL_GPL(lm3533_ctrlbank_get_##_name);
lm3533_ctrlbank_set(brightness, BRIGHTNESS);
lm3533_ctrlbank_get(brightness, BRIGHTNESS);
/*
* PWM-input control mask:
*
* bit 5 - PWM-input enabled in Zone 4
* bit 4 - PWM-input enabled in Zone 3
* bit 3 - PWM-input enabled in Zone 2
* bit 2 - PWM-input enabled in Zone 1
* bit 1 - PWM-input enabled in Zone 0
* bit 0 - PWM-input enabled
*/
lm3533_ctrlbank_set(pwm, PWM);
lm3533_ctrlbank_get(pwm, PWM);
MODULE_AUTHOR("Johan Hovold <jhovold@gmail.com>");
MODULE_DESCRIPTION("LM3533 Control Bank interface");
MODULE_LICENSE("GPL");
This diff is collapsed.
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#define GPIOBASE 0x44 #define GPIOBASE 0x44
#define GPIO_IO_SIZE 64 #define GPIO_IO_SIZE 64
#define GPIO_IO_SIZE_CENTERTON 128
#define WDTBASE 0x84 #define WDTBASE 0x84
#define WDT_IO_SIZE 64 #define WDT_IO_SIZE 64
...@@ -68,7 +69,7 @@ static struct resource wdt_sch_resource = { ...@@ -68,7 +69,7 @@ static struct resource wdt_sch_resource = {
static struct mfd_cell tunnelcreek_cells[] = { static struct mfd_cell tunnelcreek_cells[] = {
{ {
.name = "tunnelcreek_wdt", .name = "ie6xx_wdt",
.num_resources = 1, .num_resources = 1,
.resources = &wdt_sch_resource, .resources = &wdt_sch_resource,
}, },
...@@ -77,6 +78,7 @@ static struct mfd_cell tunnelcreek_cells[] = { ...@@ -77,6 +78,7 @@ static struct mfd_cell tunnelcreek_cells[] = {
static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = { static DEFINE_PCI_DEVICE_TABLE(lpc_sch_ids) = {
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_SCH_LPC) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) }, { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ITC_LPC) },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CENTERTON_ILB) },
{ 0, } { 0, }
}; };
MODULE_DEVICE_TABLE(pci, lpc_sch_ids); MODULE_DEVICE_TABLE(pci, lpc_sch_ids);
...@@ -115,7 +117,11 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, ...@@ -115,7 +117,11 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,
} }
gpio_sch_resource.start = base_addr; gpio_sch_resource.start = base_addr;
gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1;
if (id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB)
gpio_sch_resource.end = base_addr + GPIO_IO_SIZE_CENTERTON - 1;
else
gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1;
for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++) for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++)
lpc_sch_cells[i].id = id->device; lpc_sch_cells[i].id = id->device;
...@@ -125,7 +131,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev, ...@@ -125,7 +131,8 @@ static int __devinit lpc_sch_probe(struct pci_dev *dev,
if (ret) if (ret)
goto out_dev; goto out_dev;
if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC) { if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC
|| id->device == PCI_DEVICE_ID_INTEL_CENTERTON_ILB) {
pci_read_config_dword(dev, WDTBASE, &base_addr_cfg); pci_read_config_dword(dev, WDTBASE, &base_addr_cfg);
if (!(base_addr_cfg & (1 << 31))) { if (!(base_addr_cfg & (1 << 31))) {
dev_err(&dev->dev, "Decode of the WDT I/O range disabled\n"); dev_err(&dev->dev, "Decode of the WDT I/O range disabled\n");
...@@ -167,18 +174,7 @@ static struct pci_driver lpc_sch_driver = { ...@@ -167,18 +174,7 @@ static struct pci_driver lpc_sch_driver = {
.remove = __devexit_p(lpc_sch_remove), .remove = __devexit_p(lpc_sch_remove),
}; };
static int __init lpc_sch_init(void) module_pci_driver(lpc_sch_driver);
{
return pci_register_driver(&lpc_sch_driver);
}
static void __exit lpc_sch_exit(void)
{
pci_unregister_driver(&lpc_sch_driver);
}
module_init(lpc_sch_init);
module_exit(lpc_sch_exit);
MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>"); MODULE_AUTHOR("Denis Turischev <denis@compulab.co.il>");
MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH"); MODULE_DESCRIPTION("LPC interface for Intel Poulsbo SCH");
......
This diff is collapsed.
/*
* max77693.c - mfd core driver for the MAX 77693
*
* Copyright (C) 2012 Samsung Electronics
* SangYoung Son <hello.son@smasung.com>
*
* This program is not provided / owned by Maxim Integrated Products.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This driver is based on max8997.c
*/
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/pm_runtime.h>
#include <linux/mutex.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max77693.h>
#include <linux/mfd/max77693-private.h>
#include <linux/regulator/machine.h>
#include <linux/regmap.h>
#define I2C_ADDR_PMIC (0xCC >> 1) /* Charger, Flash LED */
#define I2C_ADDR_MUIC (0x4A >> 1)
#define I2C_ADDR_HAPTIC (0x90 >> 1)
static struct mfd_cell max77693_devs[] = {
{ .name = "max77693-pmic", },
{ .name = "max77693-charger", },
{ .name = "max77693-flash", },
{ .name = "max77693-muic", },
{ .name = "max77693-haptic", },
};
int max77693_read_reg(struct regmap *map, u8 reg, u8 *dest)
{
unsigned int val;
int ret;
ret = regmap_read(map, reg, &val);
*dest = val;
return ret;
}
EXPORT_SYMBOL_GPL(max77693_read_reg);
int max77693_bulk_read(struct regmap *map, u8 reg, int count, u8 *buf)
{
int ret;
ret = regmap_bulk_read(map, reg, buf, count);
return ret;
}
EXPORT_SYMBOL_GPL(max77693_bulk_read);
int max77693_write_reg(struct regmap *map, u8 reg, u8 value)
{
int ret;
ret = regmap_write(map, reg, value);
return ret;
}
EXPORT_SYMBOL_GPL(max77693_write_reg);
int max77693_bulk_write(struct regmap *map, u8 reg, int count, u8 *buf)
{
int ret;
ret = regmap_bulk_write(map, reg, buf, count);
return ret;
}
EXPORT_SYMBOL_GPL(max77693_bulk_write);
int max77693_update_reg(struct regmap *map, u8 reg, u8 val, u8 mask)
{
int ret;
ret = regmap_update_bits(map, reg, mask, val);
return ret;
}
EXPORT_SYMBOL_GPL(max77693_update_reg);
static const struct regmap_config max77693_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.max_register = MAX77693_PMIC_REG_END,
};
static int max77693_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct max77693_dev *max77693;
struct max77693_platform_data *pdata = i2c->dev.platform_data;
u8 reg_data;
int ret = 0;
max77693 = devm_kzalloc(&i2c->dev,
sizeof(struct max77693_dev), GFP_KERNEL);
if (max77693 == NULL)
return -ENOMEM;
max77693->regmap = devm_regmap_init_i2c(i2c, &max77693_regmap_config);
if (IS_ERR(max77693->regmap)) {
ret = PTR_ERR(max77693->regmap);
dev_err(max77693->dev,"failed to allocate register map: %d\n",
ret);
goto err_regmap;
}
i2c_set_clientdata(i2c, max77693);
max77693->dev = &i2c->dev;
max77693->i2c = i2c;
max77693->irq = i2c->irq;
max77693->type = id->driver_data;
if (!pdata)
goto err_regmap;
max77693->wakeup = pdata->wakeup;
mutex_init(&max77693->iolock);
if (max77693_read_reg(max77693->regmap,
MAX77693_PMIC_REG_PMIC_ID2, &reg_data) < 0) {
dev_err(max77693->dev, "device not found on this channel\n");
ret = -ENODEV;
goto err_regmap;
} else
dev_info(max77693->dev, "device ID: 0x%x\n", reg_data);
max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
i2c_set_clientdata(max77693->muic, max77693);
max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
i2c_set_clientdata(max77693->haptic, max77693);
ret = max77693_irq_init(max77693);
if (ret < 0)
goto err_mfd;
pm_runtime_set_active(max77693->dev);
ret = mfd_add_devices(max77693->dev, -1, max77693_devs,
ARRAY_SIZE(max77693_devs), NULL, 0);
if (ret < 0)
goto err_mfd;
device_init_wakeup(max77693->dev, pdata->wakeup);
return ret;
err_mfd:
i2c_unregister_device(max77693->muic);
i2c_unregister_device(max77693->haptic);
err_regmap:
kfree(max77693);
return ret;
}
static int max77693_i2c_remove(struct i2c_client *i2c)
{
struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
mfd_remove_devices(max77693->dev);
i2c_unregister_device(max77693->muic);
i2c_unregister_device(max77693->haptic);
return 0;
}
static const struct i2c_device_id max77693_i2c_id[] = {
{ "max77693", TYPE_MAX77693 },
{ }
};
MODULE_DEVICE_TABLE(i2c, max77693_i2c_id);
static int max77693_suspend(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))
irq_set_irq_wake(max77693->irq, 1);
return 0;
}
static int max77693_resume(struct device *dev)
{
struct i2c_client *i2c = container_of(dev, struct i2c_client, dev);
struct max77693_dev *max77693 = i2c_get_clientdata(i2c);
if (device_may_wakeup(dev))
irq_set_irq_wake(max77693->irq, 0);
return max77693_irq_resume(max77693);
}
const struct dev_pm_ops max77693_pm = {
.suspend = max77693_suspend,
.resume = max77693_resume,
};
static struct i2c_driver max77693_i2c_driver = {
.driver = {
.name = "max77693",
.owner = THIS_MODULE,
.pm = &max77693_pm,
},
.probe = max77693_i2c_probe,
.remove = max77693_i2c_remove,
.id_table = max77693_i2c_id,
};
static int __init max77693_i2c_init(void)
{
return i2c_add_driver(&max77693_i2c_driver);
}
/* init early so consumer devices can complete system boot */
subsys_initcall(max77693_i2c_init);
static void __exit max77693_i2c_exit(void)
{
i2c_del_driver(&max77693_i2c_driver);
}
module_exit(max77693_i2c_exit);
MODULE_DESCRIPTION("MAXIM 77693 multi-function core driver");
MODULE_AUTHOR("SangYoung, Son <hello.son@samsung.com>");
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -122,7 +122,6 @@ MODULE_DEVICE_TABLE(spi, stmpe_id); ...@@ -122,7 +122,6 @@ MODULE_DEVICE_TABLE(spi, stmpe_id);
static struct spi_driver stmpe_spi_driver = { static struct spi_driver stmpe_spi_driver = {
.driver = { .driver = {
.name = "stmpe-spi", .name = "stmpe-spi",
.bus = &spi_bus_type,
.owner = THIS_MODULE, .owner = THIS_MODULE,
#ifdef CONFIG_PM #ifdef CONFIG_PM
.pm = &stmpe_dev_pm_ops, .pm = &stmpe_dev_pm_ops,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -757,6 +757,7 @@ int twl4030_init_irq(struct device *dev, int irq_num) ...@@ -757,6 +757,7 @@ int twl4030_init_irq(struct device *dev, int irq_num)
dev_err(dev, "could not claim irq%d: %d\n", irq_num, status); dev_err(dev, "could not claim irq%d: %d\n", irq_num, status);
goto fail_rqirq; goto fail_rqirq;
} }
enable_irq_wake(irq_num);
return irq_base; return irq_base;
fail_rqirq: fail_rqirq:
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment