* Re: [PATCH] staging: android: binder: move to the "real" part of the kernel
From: Arve Hjønnevåg @ 2014-10-20 23:32 UTC (permalink / raw)
To: Dan Carpenter
Cc: Greg Kroah-Hartman,
devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b@public.gmane.org,
Anup Patel, linux-api-u79uwXL29TY76Z2rM5mHXA, LKML, John Stultz,
Rebecca Schultz Zavin, Santosh Shilimkar, Sumit Semwal,
Christoffer Dall
In-Reply-To: <20141020092049.GJ23154@mwanda>
On Mon, Oct 20, 2014 at 2:20 AM, Dan Carpenter <dan.carpenter-QHcLZuEGTsthl2p70BpVqQ@public.gmane.orgm> wrote:
> On Mon, Oct 20, 2014 at 06:05:47AM +0800, Greg Kroah-Hartman wrote:
>> On Fri, Oct 17, 2014 at 12:26:01PM +0300, Dan Carpenter wrote:
>> > The code isn't very beautiful and there are lots of details wrong like
>> > the error codes.
>>
>> Really, what is wrong with the existing error code usages?
>>
>
> I guess I was mostly looking at binder_ioctl(), the rest of the code
> seems better.
>
> I feel like we went directly from "This code is never going in so there
> is no need to look at it." to "This code is going in in one week so
> there is no time to look at it."
>
> How often do people rely on proc_no_lock=1 to make this work? People
> are saying on the internet that you don't need acurate information so
> you should disable locking as a speed up.
> http://www.programdevelop.com/1821706/. It seems like a bad idea to
> provide provide the "run fast and crash" option.
That is not what this switch is for. It is only there to debug the
driver if it gets stuck with the lock held. I would not object to
adding a config option to remove this param by default.
>
> Why is binder_set_nice needed? Some comments would help here.
The driver has some support for priority inheritance.
>
> 434 static void binder_set_nice(long nice)
> 435 {
> 436 long min_nice;
> 437
> 438 if (can_nice(current, nice)) {
> 439 set_user_nice(current, nice);
> 440 return;
> 441 }
> 442 min_nice = rlimit_to_nice(current->signal->rlim[RLIMIT_NICE].rlim_cur);
> 443 binder_debug(BINDER_DEBUG_PRIORITY_CAP,
> 444 "%d: nice value %ld not allowed use %ld instead\n",
> 445 current->pid, nice, min_nice);
> 446 set_user_nice(current, min_nice);
> 447 if (min_nice <= MAX_NICE)
> 448 return;
>
> It's harmless but wierd to check if min_nice is valid after we already
> called set_user_nice().
I don't remember why I did this, but I agree it is weird.
>
> 449 binder_user_error("%d RLIMIT_NICE not set\n", current->pid);
> 450 }
>
> Random comment:
>
> 709 has_page_addr =
> 710 (void *)(((uintptr_t)buffer->data + buffer_size) & PAGE_MASK);
>
> The casting on "buffer->data" ugly and inconsistent. There should be
> a function:
Other code in the kernel seems to do this the same way (although most
cast to unsigned long instead of uintptr_t). This code rounds down to
the start of of the page, and needs to cast to an integer type for
this. Adding a global kernel helper for this would be better than a
binder specific one. The existing PAGE_ALIGN function, which rounds
up, still needs casts to use with pointer types though.
> void *buffer_data(struct binder_buffer *buffer)
> {
> return buffer.data;
> }
>
> That way this becomes:
> has_page_addr = (buffer_data(buffer) + buffer_size) & PAGE_MASK);
I don't think this will compile.
>
> The "has_page_addr" variable name is misleading, because we're not
> storing true/false. We're storing the last page address.
It is the address of a page we already have mapped, not the last
address of the new allocation.
>
> 711 if (n == NULL) {
> 712 if (size + sizeof(struct binder_buffer) + 4 >= buffer_size)
> 713 buffer_size = size; /* no room for other buffers */
> 714 else
> 715 buffer_size = size + sizeof(struct binder_buffer);
> 716 }
> 717 end_page_addr =
> 718 (void *)PAGE_ALIGN((uintptr_t)buffer->data + buffer_size);
> 719 if (end_page_addr > has_page_addr)
> 720 end_page_addr = has_page_addr;
> 721 if (binder_update_page_range(proc, 1,
> 722 (void *)PAGE_ALIGN((uintptr_t)buffer->data), end_page_addr, NULL))
> 723 return NULL;
>
> The alignment here is confusing because we don't align buffer->data
> below.
binder_update_page_range allocates and maps pages. buffer->data will
point to a range within the allocated pages.
>
> 724
> 725 rb_erase(best_fit, &proc->free_buffers);
> 726 buffer->free = 0;
> 727 binder_insert_allocated_buffer(proc, buffer);
> 728 if (buffer_size != size) {
> 729 struct binder_buffer *new_buffer = (void *)buffer->data + size;
> ^^^^^^^^^^^^^^^^^^^^
> I don't really understand when buffer->data has to be page aligned and
> when not. This code has very few comments.
>
buffer->data never needs to be page aligned. The code above rounds to
page boundaries to allocate new pages as needed.
> 730
> 731 list_add(&new_buffer->entry, &buffer->entry);
> 732 new_buffer->free = 1;
> 733 binder_insert_free_buffer(proc, new_buffer);
> 734 }
>
> Does the stop_on_user_error option work? There should be some
> documentation for this stuff.
>
Yes.
> regards,
> dan carpenter
>
--
Arve Hjønnevåg
^ permalink raw reply
* Re: [PATCHv4 RESEND 0/3] syscalls,x86: Add execveat() system call
From: Andy Lutomirski @ 2014-10-20 22:48 UTC (permalink / raw)
To: David Drysdale
Cc: Eric W. Biederman, Alexander Viro, Meredydd Luff,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrew Morton,
Kees Cook, Arnd Bergmann, X86 ML, linux-arch, Linux API
In-Reply-To: <CAHse=S-Xyk7CFn=tAGzo+tuUFt+04aBw+mGQmi=kWAaBJGALBw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, Oct 20, 2014 at 6:48 AM, David Drysdale <drysdale-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org> wrote:
> On Sun, Oct 19, 2014 at 1:20 AM, Eric W. Biederman
> <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
>> Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org> writes:
>>
>>> [Added Eric Biederman, since I think your tree might be a reasonable
>>> route forward for these patches.]
>>>
>>> On Thu, Jun 5, 2014 at 6:40 AM, David Drysdale <drysdale-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org> wrote:
>>>> Resending, adding cc:linux-api.
>>>>
>>>> Also, it may help to add a little more background -- this patch is
>>>> needed as a (small) part of implementing Capsicum in the Linux kernel.
>>>>
>>>> Capsicum is a security framework that has been present in FreeBSD since
>>>> version 9.0 (Jan 2012), and is based on concepts from object-capability
>>>> security [1].
>>>>
>>>> One of the features of Capsicum is capability mode, which locks down
>>>> access to global namespaces such as the filesystem hierarchy. In
>>>> capability mode, /proc is thus inaccessible and so fexecve(3) doesn't
>>>> work -- hence the need for a kernel-space
>>>
>>> I just found myself wanting this syscall for another reason: injecting
>>> programs into sandboxes or otherwise heavily locked-down namespaces.
>>>
>>> For example, I want to be able to reliably do something like nsenter
>>> --namespace-flags-here toybox sh. Toybox's shell is unusual in that
>>> it is more or less fully functional, so this should Just Work (tm),
>>> except that the toybox binary might not exist in the namespace being
>>> entered. If execveat were available, I could rig nsenter or a similar
>>> tool to open it with O_CLOEXEC, enter the namespace, and then call
>>> execveat.
>>>
>>> Is there any reason that these patches can't be merged more or less as
>>> is for 3.19?
>>
>> Yes. There is a silliness in how it implements fexecve. The fexecve
>> case should be use the empty string "" not a NULL pointer to indication
>> that. That change will then harmonize execveat with the other ...at
>> system calls and simplify the code and remove a special case. I believe
>> using the empty string "" requires implementing the AT_EMPTY_PATH flag.
>
> Good point -- I'll shift to "" + AT_EMPTY_PATH.
Pending a better idea, I would also see if the patches can be changed
to return an error if d_path ends up with an "(unreachable)" thing
rather than failing inexplicably later on.
--Andy
^ permalink raw reply
* Re: [PATCH 2/2] fs: Support compiling out sendfile
From: josh @ 2014-10-20 22:24 UTC (permalink / raw)
To: Pieter Smith
Cc: Alexander Viro, Andrew Morton, Eric Paris, Matt Turner,
Michal Hocko, Paul E. McKenney, Fabian Frederick, Tejun Heo,
蔡正龙, Luis R. Rodriguez, Peter Foley,
Konstantin Khlebnikov, Eric W. Biederman, H. Peter Anvin,
Oleg Nesterov, Andy Lutomirski, David Herrmann, Kees Cook,
linux-fsdevel, open list, open list:ABI/API
In-Reply-To: <1413841728-1313-2-git-send-email-pieter@boesman.nl>
On Mon, Oct 20, 2014 at 11:48:37PM +0200, Pieter Smith wrote:
> Many embedded systems will not need this syscall, and omitting it
> saves space. Add a new EXPERT config option CONFIG_SENDFILE_SYSCALL
> (default y) to support compiling it out.
Nice work, thanks!
If there are no objections, and nobody has a tree they'd rather carry
this through, I'll take the series through the tiny tree when it's ready
to merge.
> bloat-o-meter:
> add/remove: 0/4 grow/shrink: 5/0 up/down: 23/-751 (-728)
> function old new delta
> sys_pwritev 115 122 +7
> sys_preadv 115 122 +7
> fdput_pos 29 36 +7
> sys_pwrite64 115 116 +1
> sys_pread64 115 116 +1
> fdput 11 - -11
> sys_sendfile 122 - -122
> sys_sendfile64 126 - -126
> do_sendfile 492 - -492
Interesting inlining decisions by GCC here. Got a bloat-o-meter for the
two-patch series, by any chance? (Also, is this with tinyconfig? In
particular, with OPTIMIZE_INLINING and OPTIMIZE_FOR_SIZE?) I'm
wondering if moving sendfile to a separate file made GCC put fdput
out-of-line, and compiling it out reversed that again.
> Signed-off-by: Pieter Smith <pieter@boesman.nl>
Reviewed-by: Josh Triplett <josh@joshtriplett.org>
> ---
> fs/Makefile | 3 ++-
> init/Kconfig | 10 ++++++++++
> kernel/sys_ni.c | 4 ++++
> 3 files changed, 16 insertions(+), 1 deletion(-)
>
> diff --git a/fs/Makefile b/fs/Makefile
> index 1e3423f..1bbfea7 100644
> --- a/fs/Makefile
> +++ b/fs/Makefile
> @@ -5,7 +5,7 @@
> # Rewritten to use lists instead of if-statements.
> #
>
> -obj-y := open.o read_write.o sendfile.o file_table.o super.o \
> +obj-y := open.o read_write.o file_table.o super.o \
> char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
> ioctl.o readdir.o select.o dcache.o inode.o \
> attr.o bad_inode.o file.o filesystems.o namespace.o \
> @@ -38,6 +38,7 @@ obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o
> obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
> obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o
> obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
> +obj-$(CONFIG_SENDFILE_SYSCALL) += sendfile.o
>
> obj-$(CONFIG_FS_MBCACHE) += mbcache.o
> obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
> diff --git a/init/Kconfig b/init/Kconfig
> index 782a65b..df6785c 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -1547,6 +1547,16 @@ config ADVISE_SYSCALLS
> applications use these syscalls, you can disable this option to save
> space.
>
> +config SENDFILE_SYSCALL
> + bool "Enable sendfile syscall" if EXPERT
> + default y
> + help
> + This option enables the sendfile syscall, used by applications to copy
> + data between file descriptors. Because sendfile performs the copying
> + within the kernel, it is more efficient than the combination of read
> + and write. If building an embedded system where no applications use
> + the sendfile syscall, you can disable this option to save space.
> +
I'm thinking of adding a submenu to group config FOO_SYSCALL options. :)
I'll probably push that as part of the 3.19 merge window, as a patch on
top of all of the individual tinification options.
> config PCI_QUIRKS
> default y
> bool "Enable PCI quirk workarounds" if EXPERT
> diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
> index d4709d4..b068de7 100644
> --- a/kernel/sys_ni.c
> +++ b/kernel/sys_ni.c
> @@ -159,6 +159,10 @@ cond_syscall(sys_uselib);
> cond_syscall(sys_fadvise64);
> cond_syscall(sys_fadvise64_64);
> cond_syscall(sys_madvise);
> +cond_syscall(sys_sendfile);
> +cond_syscall(sys_sendfile64);
> +cond_syscall(compat_sys_sendfile);
> +cond_syscall(compat_sys_sendfile64);
>
> /* arch-specific weak syscall entries */
> cond_syscall(sys_pciconfig_read);
> --
> 1.9.1
>
^ permalink raw reply
* preadv2/pwritev2 rename
From: Milosz Tanski @ 2014-10-20 21:52 UTC (permalink / raw)
To: Christoph Hellwig; +Cc: Jeff Moyer, Linux API
Christoph and/or Jeff,
I updated the patch for 3.18-rc1 and I'm going to resend it as non-RFC
as I didn't get comments last time.
I only have one stupid question... I'm going to rename the calls to
preadv6 and pwritev6 (so it's more like the other syscalls: dup3,
accept4, eventfd2) but I'm not sure if i should call it preadv5 or
pwritev6 since the offset argument is split into two different
arguments (upper and lower part).
Also, In our application we were able to get about 20%-30% reduction
in response time when using this before queuing in a IO thread pool on
the read path. It's a pretty nice win in the real world.
Best,
- Milosz
--
Milosz Tanski
CTO
16 East 34th Street, 15th floor
New York, NY 10016
p: 646-253-9055
e: milosz-B5zB6C1i6pkAvxtiuMwx3w@public.gmane.org
^ permalink raw reply
* [PATCH 2/2] fs: Support compiling out sendfile
From: Pieter Smith @ 2014-10-20 21:48 UTC (permalink / raw)
To: Alexander Viro
Cc: Josh Triplett, Pieter Smith, Andrew Morton, Eric Paris,
Matt Turner, Michal Hocko, Paul E. McKenney, Fabian Frederick,
Tejun Heo, 蔡正龙, Luis R. Rodriguez,
Peter Foley, Konstantin Khlebnikov, Eric W. Biederman,
H. Peter Anvin, Oleg Nesterov, Andy Lutomirski, David Herrmann,
Kees Cook, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, open list,
open list:ABI/API
In-Reply-To: <1413841728-1313-1-git-send-email-pieter-qeJ+1H9vRZbz+pZb47iToQ@public.gmane.org>
Many embedded systems will not need this syscall, and omitting it
saves space. Add a new EXPERT config option CONFIG_SENDFILE_SYSCALL
(default y) to support compiling it out.
bloat-o-meter:
add/remove: 0/4 grow/shrink: 5/0 up/down: 23/-751 (-728)
function old new delta
sys_pwritev 115 122 +7
sys_preadv 115 122 +7
fdput_pos 29 36 +7
sys_pwrite64 115 116 +1
sys_pread64 115 116 +1
fdput 11 - -11
sys_sendfile 122 - -122
sys_sendfile64 126 - -126
do_sendfile 492 - -492
Signed-off-by: Pieter Smith <pieter-qeJ+1H9vRZbz+pZb47iToQ@public.gmane.org>
---
fs/Makefile | 3 ++-
init/Kconfig | 10 ++++++++++
kernel/sys_ni.c | 4 ++++
3 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/fs/Makefile b/fs/Makefile
index 1e3423f..1bbfea7 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -5,7 +5,7 @@
# Rewritten to use lists instead of if-statements.
#
-obj-y := open.o read_write.o sendfile.o file_table.o super.o \
+obj-y := open.o read_write.o file_table.o super.o \
char_dev.o stat.o exec.o pipe.o namei.o fcntl.o \
ioctl.o readdir.o select.o dcache.o inode.o \
attr.o bad_inode.o file.o filesystems.o namespace.o \
@@ -38,6 +38,7 @@ obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o
obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o
obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o
+obj-$(CONFIG_SENDFILE_SYSCALL) += sendfile.o
obj-$(CONFIG_FS_MBCACHE) += mbcache.o
obj-$(CONFIG_FS_POSIX_ACL) += posix_acl.o
diff --git a/init/Kconfig b/init/Kconfig
index 782a65b..df6785c 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1547,6 +1547,16 @@ config ADVISE_SYSCALLS
applications use these syscalls, you can disable this option to save
space.
+config SENDFILE_SYSCALL
+ bool "Enable sendfile syscall" if EXPERT
+ default y
+ help
+ This option enables the sendfile syscall, used by applications to copy
+ data between file descriptors. Because sendfile performs the copying
+ within the kernel, it is more efficient than the combination of read
+ and write. If building an embedded system where no applications use
+ the sendfile syscall, you can disable this option to save space.
+
config PCI_QUIRKS
default y
bool "Enable PCI quirk workarounds" if EXPERT
diff --git a/kernel/sys_ni.c b/kernel/sys_ni.c
index d4709d4..b068de7 100644
--- a/kernel/sys_ni.c
+++ b/kernel/sys_ni.c
@@ -159,6 +159,10 @@ cond_syscall(sys_uselib);
cond_syscall(sys_fadvise64);
cond_syscall(sys_fadvise64_64);
cond_syscall(sys_madvise);
+cond_syscall(sys_sendfile);
+cond_syscall(sys_sendfile64);
+cond_syscall(compat_sys_sendfile);
+cond_syscall(compat_sys_sendfile64);
/* arch-specific weak syscall entries */
cond_syscall(sys_pciconfig_read);
--
1.9.1
^ permalink raw reply related
* Re: [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag
From: Andy Lutomirski @ 2014-10-20 21:37 UTC (permalink / raw)
To: Antonios Motakis
Cc: kvmarm, iommu, Alex Williamson, Will Deacon, tech,
christoffer.dall, eric.auger, kim.phillips, marc.zyngier,
open list:VFIO DRIVER, open list:ABI/API, open list
In-Reply-To: <1413205748-6300-3-git-send-email-a.motakis@virtualopensystems.com>
On Mon, Oct 13, 2014 at 6:09 AM, Antonios Motakis
<a.motakis@virtualopensystems.com> wrote:
> We introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag to the VFIO dma map call,
> and expose its availability via the capability VFIO_DMA_NOEXEC_IOMMU.
> This way the user can control whether the XN flag will be set on the
> requested mappings. The IOMMU_NOEXEC flag needs to be available for all
> the IOMMUs of the container used.
Since you sent this to the linux-api list, I'll bite: what's the XN
flag? I know what PROT_EXEC does when you mmap something, and I
presume that vfio is mmappable, but I don't actually have any clue
what this patch does.
I assume that this does not have anything to do with a non-CPU DMA
master executing code in main memory, because that makes rather little
sense. (Or maybe it really does, in which case: weird.)
--Andy
^ permalink raw reply
* Re: [PATCH 2/5] vfio: introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag
From: Alex Williamson @ 2014-10-20 21:29 UTC (permalink / raw)
To: Antonios Motakis
Cc: open list:VFIO DRIVER, eric.auger-QSEj5FYQhm4dnm+yROfE0A,
marc.zyngier-5wv7dgnIgG8, open list:ABI/API,
will.deacon-5wv7dgnIgG8, open list,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
tech-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J,
kvmarm-FPEHb7Xf0XXUo1n7N8X6UoWGPAHP3yOg,
christoffer.dall-QSEj5FYQhm4dnm+yROfE0A
In-Reply-To: <1413205748-6300-3-git-send-email-a.motakis-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J@public.gmane.org>
On Mon, 2014-10-13 at 15:09 +0200, Antonios Motakis wrote:
> We introduce the VFIO_DMA_MAP_FLAG_NOEXEC flag to the VFIO dma map call,
> and expose its availability via the capability VFIO_DMA_NOEXEC_IOMMU.
> This way the user can control whether the XN flag will be set on the
> requested mappings. The IOMMU_NOEXEC flag needs to be available for all
> the IOMMUs of the container used.
>
> Signed-off-by: Antonios Motakis <a.motakis-lrHrjnjw1UfHK3s98zE1ajGjJy/sRE9J@public.gmane.org>
> ---
> include/uapi/linux/vfio.h | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/include/uapi/linux/vfio.h b/include/uapi/linux/vfio.h
> index 6612974..111b5e8 100644
> --- a/include/uapi/linux/vfio.h
> +++ b/include/uapi/linux/vfio.h
> @@ -29,6 +29,7 @@
> * capability is subject to change as groups are added or removed.
> */
> #define VFIO_DMA_CC_IOMMU 4
> +#define VFIO_DMA_NOEXEC_IOMMU 5
>
> /* Check if EEH is supported */
> #define VFIO_EEH 5
^^
5 is still already used. Feel free to convert to enum so we stop making
this mistake.
> @@ -401,6 +402,7 @@ struct vfio_iommu_type1_dma_map {
> __u32 flags;
> #define VFIO_DMA_MAP_FLAG_READ (1 << 0) /* readable from device */
> #define VFIO_DMA_MAP_FLAG_WRITE (1 << 1) /* writable from device */
> +#define VFIO_DMA_MAP_FLAG_NOEXEC (1 << 2) /* not executable from device */
> __u64 vaddr; /* Process virtual address */
> __u64 iova; /* IO virtual address */
> __u64 size; /* Size of mapping (bytes) */
^ permalink raw reply
* Re: [PATCH] staging: android: binder: move to the "real" part of the kernel
From: Arnd Bergmann @ 2014-10-20 17:06 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devel-gWbeCf7V1WCQmaza687I9mD2FQJk+8+b,
linux-api-u79uwXL29TY76Z2rM5mHXA, Santosh Shilimkar, John Stultz,
Arve Hjønnevåg, Sumit Semwal, Rebecca Schultz Zavin,
Christoffer Dall, Anup Patel
In-Reply-To: <20141016124741.GA3832-U8xfFu+wG4EAvxtiuMwx3w@public.gmane.org>
On Thursday 16 October 2014 14:47:41 Greg Kroah-Hartman wrote:
> From: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>
>
> The Android binder code has been "stable" for many years now. No matter
> what comes in the future, we are going to have to support this API, so
> might as well move it to the "real" part of the kernel as there's no
> real work that needs to be done to the existing code.
>
> Signed-off-by: Greg Kroah-Hartman <gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r@public.gmane.org>
> ---
>
> This was discussed in the Android miniconf at the Plumbers conference.
> If anyone has any objections to this, please let me know, otherwise I'm
> queueing this up for 3.19-rc1
I'm worried about the user interface: since graduating binder out of
staging with the existing ioctl interface has never been discussed
as a real option and (I assume) everybody expected the way forward
would be to have a replacement, I don't think it ever received the
attention it should have. Specific concerns are:
- I don't think there has been an audit of which subset of the API
is actually required. IIRC, it was said initially that actual
applications don't use all the features, and that we should have
a smaller attack surface.
- Using kernel pointers in user space interfaces is an information
leak that can be used to construct an exploit. (I don't know if
this is still used that way, I think it was doing it last
time I checked).
- The driver supports two versions of the user interface (v7 and
v8), but only one of them can be selected at compile-time, and
an 'allmodconfig' kernel will only include the deprecated one
on 32-bit machines.
- The implementation is not namespace-aware and will cause
information to be shared across containers in a potentially
harmful way.
If we graduate the driver from staging, it should IMHO at least
be useful in containers to run Android user space safely.
Arnd
^ permalink raw reply
* Re: [PATCH v2 2/5] mfd: max77693: Map charger device to its own of_node
From: Krzysztof Kozlowski @ 2014-10-20 15:09 UTC (permalink / raw)
To: Lee Jones
Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA, Samuel Ortiz,
linux-api-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA, Kyungmin Park,
Marek Szyprowski, Bartlomiej Zolnierkiewicz
In-Reply-To: <20141020150630.GB26784@x1>
On pon, 2014-10-20 at 16:06 +0100, Lee Jones wrote:
> On Mon, 20 Oct 2014, Krzysztof Kozlowski wrote:
>
> > Add a "maxim,max77693-charger" of_compatible to the mfd_cell so the MFD
> > child device (the charger) will have its own of_node set. This will be
> > used by the max77693 charger driver in next patches to obtain battery
> > configuration from DTS.
> >
> > Signed-off-by: Krzysztof Kozlowski <k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
> > ---
> > drivers/mfd/max77693.c | 5 ++++-
> > 1 file changed, 4 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
> > index cf008f45968c..2277a11b6629 100644
> > --- a/drivers/mfd/max77693.c
> > +++ b/drivers/mfd/max77693.c
> > @@ -43,7 +43,10 @@
> >
> > static const struct mfd_cell max77693_devs[] = {
> > { .name = "max77693-pmic", },
> > - { .name = "max77693-charger", },
> > + {
> > + .name = "max77693-charger",
> > + .of_compatible = "maxim,max77693-charger",
> > + },
> > { .name = "max77693-muic", },
> > { .name = "max77693-haptic", },
> > {
>
> I'm guessing this can be applied separately?
Yes. Patch 3/5 also (it adds necessary defines and symbols for
chargers).
Best regards,
Krzysztof
^ permalink raw reply
* Re: [PATCH v2 2/5] mfd: max77693: Map charger device to its own of_node
From: Lee Jones @ 2014-10-20 15:06 UTC (permalink / raw)
To: Krzysztof Kozlowski
Cc: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
linux-kernel, linux-pm, Samuel Ortiz, linux-api, devicetree,
Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz
In-Reply-To: <1413808489-3524-3-git-send-email-k.kozlowski@samsung.com>
On Mon, 20 Oct 2014, Krzysztof Kozlowski wrote:
> Add a "maxim,max77693-charger" of_compatible to the mfd_cell so the MFD
> child device (the charger) will have its own of_node set. This will be
> used by the max77693 charger driver in next patches to obtain battery
> configuration from DTS.
>
> Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
> ---
> drivers/mfd/max77693.c | 5 ++++-
> 1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
> index cf008f45968c..2277a11b6629 100644
> --- a/drivers/mfd/max77693.c
> +++ b/drivers/mfd/max77693.c
> @@ -43,7 +43,10 @@
>
> static const struct mfd_cell max77693_devs[] = {
> { .name = "max77693-pmic", },
> - { .name = "max77693-charger", },
> + {
> + .name = "max77693-charger",
> + .of_compatible = "maxim,max77693-charger",
> + },
> { .name = "max77693-muic", },
> { .name = "max77693-haptic", },
> {
I'm guessing this can be applied separately?
--
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org │ Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog
^ permalink raw reply
* Re: [PATCHv4 RESEND 0/3] syscalls,x86: Add execveat() system call
From: David Drysdale @ 2014-10-20 13:48 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Andy Lutomirski, Alexander Viro, Meredydd Luff,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Thomas Gleixner, Ingo Molnar, H. Peter Anvin, Andrew Morton,
Kees Cook, Arnd Bergmann, X86 ML, linux-arch, Linux API
In-Reply-To: <87zjcszz8y.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
On Sun, Oct 19, 2014 at 1:20 AM, Eric W. Biederman
<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
> Andy Lutomirski <luto-kltTT9wpgjJwATOyAt5JVQ@public.gmane.org> writes:
>
>> [Added Eric Biederman, since I think your tree might be a reasonable
>> route forward for these patches.]
>>
>> On Thu, Jun 5, 2014 at 6:40 AM, David Drysdale <drysdale-hpIqsD4AKlfQT0dZR+AlfA@public.gmane.org> wrote:
>>> Resending, adding cc:linux-api.
>>>
>>> Also, it may help to add a little more background -- this patch is
>>> needed as a (small) part of implementing Capsicum in the Linux kernel.
>>>
>>> Capsicum is a security framework that has been present in FreeBSD since
>>> version 9.0 (Jan 2012), and is based on concepts from object-capability
>>> security [1].
>>>
>>> One of the features of Capsicum is capability mode, which locks down
>>> access to global namespaces such as the filesystem hierarchy. In
>>> capability mode, /proc is thus inaccessible and so fexecve(3) doesn't
>>> work -- hence the need for a kernel-space
>>
>> I just found myself wanting this syscall for another reason: injecting
>> programs into sandboxes or otherwise heavily locked-down namespaces.
>>
>> For example, I want to be able to reliably do something like nsenter
>> --namespace-flags-here toybox sh. Toybox's shell is unusual in that
>> it is more or less fully functional, so this should Just Work (tm),
>> except that the toybox binary might not exist in the namespace being
>> entered. If execveat were available, I could rig nsenter or a similar
>> tool to open it with O_CLOEXEC, enter the namespace, and then call
>> execveat.
>>
>> Is there any reason that these patches can't be merged more or less as
>> is for 3.19?
>
> Yes. There is a silliness in how it implements fexecve. The fexecve
> case should be use the empty string "" not a NULL pointer to indication
> that. That change will then harmonize execveat with the other ...at
> system calls and simplify the code and remove a special case. I believe
> using the empty string "" requires implementing the AT_EMPTY_PATH flag.
Good point -- I'll shift to "" + AT_EMPTY_PATH.
> For sandboxes execveat seems to make a great deal of sense. I can
> get the same functionality by passing in a directory file descriptor
> calling fchdir and execve so this should not introduce any new security
> holes. And using the final file descriptor removes a race.
>
> AT_SYMLINK_NOFOLLOW seems to have some limited utility as well, although
> for exec I don't know what problems it can solve.
>
> Until I am done moving I won't have time to pick this up, and the code
> clearly needs another revision but I will be happy to work to see that
> we get a sane execveat implemented.
If it helps, I can push out another revision in the next couple of days.
> Eric
>
> p.s. I don't believe there are any namespaces issues where doing
> something with execveat flags make sense.
>
>
^ permalink raw reply
* Re: [PATCH] staging: android: binder: move to the "real" part of the kernel
From: Dan Carpenter @ 2014-10-20 12:45 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: devel, Anup Patel, Linux API, lkml, Arve Hjønnevåg,
Santosh Shilimkar, Michael Kerrisk (man-pages),
Rebecca Schultz Zavin, John Stultz, Sumit Semwal,
Christoffer Dall
In-Reply-To: <20141016231457.GB13592@kroah.com>
Having documentation would help reviewers.
Here is some documentation I found online.
http://www.phonesdevelopers.com/1793504/
But it seems like it was originally written in another language and auto
translated to English.
I don't see who is going to maintain this, if no one has time to even
document how it's supposed to work...
regards,
dan carpenter
^ permalink raw reply
* [PATCH v2 5/5] Documentation: charger: max77693: Document exported sysfs entry
From: Krzysztof Kozlowski @ 2014-10-20 12:34 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
linux-kernel, linux-pm, Samuel Ortiz, Lee Jones, linux-api,
devicetree
Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
Krzysztof Kozlowski
In-Reply-To: <1413808489-3524-1-git-send-email-k.kozlowski@samsung.com>
Document the settings exported by max77693 charger driver through sysfs
entries:
- fast_charge_timer
- top_off_threshold_current
- top_off_timer
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
Documentation/ABI/testing/sysfs-class-power | 42 +++++++++++++++++++++++++++++
1 file changed, 42 insertions(+)
diff --git a/Documentation/ABI/testing/sysfs-class-power b/Documentation/ABI/testing/sysfs-class-power
index 909e7602c717..369d2a2d7d3e 100644
--- a/Documentation/ABI/testing/sysfs-class-power
+++ b/Documentation/ABI/testing/sysfs-class-power
@@ -32,3 +32,45 @@ Description:
Valid values:
- 5, 6 or 7 (hours),
- 0: disabled.
+
+What: /sys/class/power_supply/max77693-charger/device/fast_charge_timer
+Date: January 2015
+KernelVersion: 3.19.0
+Contact: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Description:
+ This entry shows and sets the maximum time the max77693
+ charger operates in fast-charge mode. When the timer expires
+ the device will terminate fast-charge mode (charging current
+ will drop to 0 A) and will trigger interrupt.
+
+ Valid values:
+ - 4 - 16 (hours), step by 2 (rounded down)
+ - 0: disabled.
+
+What: /sys/class/power_supply/max77693-charger/device/top_off_threshold_current
+Date: January 2015
+KernelVersion: 3.19.0
+Contact: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Description:
+ This entry shows and sets the charging current threshold for
+ entering top-off charging mode. When charging current in fast
+ charge mode drops below this value, the charger will trigger
+ interrupt and start top-off charging mode.
+
+ Valid values:
+ - 100000 - 200000 (microamps), step by 25000 (rounded down)
+ - 200000 - 350000 (microamps), step by 50000 (rounded down)
+ - 0: disabled.
+
+What: /sys/class/power_supply/max77693-charger/device/top_off_timer
+Date: January 2015
+KernelVersion: 3.19.0
+Contact: Krzysztof Kozlowski <k.kozlowski@samsung.com>
+Description:
+ This entry shows and sets the maximum time the max77693
+ charger operates in top-off charge mode. When the timer expires
+ the device will terminate top-off charge mode (charging current
+ will drop to 0 A) and will trigger interrupt.
+
+ Valid values:
+ - 0 - 70 (minutes), step by 10 (rounded down)
--
1.9.1
^ permalink raw reply related
* [PATCH v2 4/5] power: max77693: Add charger driver for Maxim 77693
From: Krzysztof Kozlowski @ 2014-10-20 12:34 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA, Samuel Ortiz, Lee Jones,
linux-api-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
Krzysztof Kozlowski
In-Reply-To: <1413808489-3524-1-git-send-email-k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Add new driver for Maxim 77693 switch-mode charger (part of max77693
MFD driver) providing power supply class information to userspace.
The charger has +20V tolerant input. Current input can be set from 0 to
2.58 A. The charger can deliver up to 2.1 A to the battery or 3.5 A to
the system (when supplying additional current from battery to system).
The driver is configured through DTS (battery and system related
settings) and sysfs entries (timers and top-off charging threshold).
Signed-off-by: Krzysztof Kozlowski <k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
drivers/power/Kconfig | 6 +
drivers/power/Makefile | 1 +
drivers/power/max77693_charger.c | 763 +++++++++++++++++++++++++++++++++++++++
3 files changed, 770 insertions(+)
create mode 100644 drivers/power/max77693_charger.c
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 0108c2af005b..77e6cd7bb801 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -332,6 +332,12 @@ config CHARGER_MAX14577
Say Y to enable support for the battery charger control sysfs and
platform data of MAX14577/77836 MUICs.
+config CHARGER_MAX77693
+ tristate "Maxim MAX77693 battery charger driver"
+ depends on MFD_MAX77693
+ help
+ Say Y to enable support for the Maxim MAX77693 battery charger.
+
config CHARGER_MAX8997
tristate "Maxim MAX8997/MAX8966 PMIC battery charger driver"
depends on MFD_MAX8997 && REGULATOR_MAX8997
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index dfa894273926..2d7ad66cc7d6 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -50,6 +50,7 @@ obj-$(CONFIG_CHARGER_LP8788) += lp8788-charger.o
obj-$(CONFIG_CHARGER_GPIO) += gpio-charger.o
obj-$(CONFIG_CHARGER_MANAGER) += charger-manager.o
obj-$(CONFIG_CHARGER_MAX14577) += max14577_charger.o
+obj-$(CONFIG_CHARGER_MAX77693) += max77693_charger.o
obj-$(CONFIG_CHARGER_MAX8997) += max8997_charger.o
obj-$(CONFIG_CHARGER_MAX8998) += max8998_charger.o
obj-$(CONFIG_CHARGER_BQ2415X) += bq2415x_charger.o
diff --git a/drivers/power/max77693_charger.c b/drivers/power/max77693_charger.c
new file mode 100644
index 000000000000..dfdbcc2f0795
--- /dev/null
+++ b/drivers/power/max77693_charger.c
@@ -0,0 +1,763 @@
+/*
+ * max77693_charger.c - Battery charger driver for the Maxim 77693
+ *
+ * Copyright (C) 2014 Samsung Electronics
+ * Krzysztof Kozlowski <k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+#include <linux/regmap.h>
+#include <linux/mfd/max77693.h>
+#include <linux/mfd/max77693-private.h>
+
+static const char *max77693_charger_name = "max77693-charger";
+static const char *max77693_charger_model = "MAX77693";
+static const char *max77693_charger_manufacturer = "Maxim Integrated";
+
+struct max77693_charger {
+ struct device *dev;
+ struct max77693_dev *max77693;
+ struct power_supply charger;
+
+ struct max77693_charger_platform_data *pdata;
+};
+
+static int max77693_get_charger_state(struct regmap *regmap)
+{
+ int state;
+ unsigned int data;
+
+ if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0)
+ return POWER_SUPPLY_STATUS_UNKNOWN;
+
+ data &= CHG_DETAILS_01_CHG_MASK;
+ data >>= CHG_DETAILS_01_CHG_SHIFT;
+
+ switch (data) {
+ case MAX77693_CHARGING_PREQUALIFICATION:
+ case MAX77693_CHARGING_FAST_CONST_CURRENT:
+ case MAX77693_CHARGING_FAST_CONST_VOLTAGE:
+ case MAX77693_CHARGING_TOP_OFF:
+ /* In high temp the charging current is reduced, but still charging */
+ case MAX77693_CHARGING_HIGH_TEMP:
+ state = POWER_SUPPLY_STATUS_CHARGING;
+ break;
+ case MAX77693_CHARGING_DONE:
+ state = POWER_SUPPLY_STATUS_FULL;
+ break;
+ case MAX77693_CHARGING_TIMER_EXPIRED:
+ case MAX77693_CHARGING_THERMISTOR_SUSPEND:
+ state = POWER_SUPPLY_STATUS_NOT_CHARGING;
+ break;
+ case MAX77693_CHARGING_OFF:
+ case MAX77693_CHARGING_OVER_TEMP:
+ case MAX77693_CHARGING_WATCHDOG_EXPIRED:
+ state = POWER_SUPPLY_STATUS_DISCHARGING;
+ break;
+ case MAX77693_CHARGING_RESERVED:
+ default:
+ state = POWER_SUPPLY_STATUS_UNKNOWN;
+ }
+
+ return state;
+}
+
+static int max77693_get_charge_type(struct regmap *regmap)
+{
+ int state;
+ unsigned int data;
+
+ if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0)
+ return POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+
+ data &= CHG_DETAILS_01_CHG_MASK;
+ data >>= CHG_DETAILS_01_CHG_SHIFT;
+
+ switch (data) {
+ case MAX77693_CHARGING_PREQUALIFICATION:
+ /*
+ * Top-off: trickle or fast? In top-off the current varies between
+ * 100 and 250 mA. It is higher than prequalification current.
+ */
+ case MAX77693_CHARGING_TOP_OFF:
+ state = POWER_SUPPLY_CHARGE_TYPE_TRICKLE;
+ break;
+ case MAX77693_CHARGING_FAST_CONST_CURRENT:
+ case MAX77693_CHARGING_FAST_CONST_VOLTAGE:
+ /* In high temp the charging current is reduced, but still charging */
+ case MAX77693_CHARGING_HIGH_TEMP:
+ state = POWER_SUPPLY_CHARGE_TYPE_FAST;
+ break;
+ case MAX77693_CHARGING_DONE:
+ case MAX77693_CHARGING_TIMER_EXPIRED:
+ case MAX77693_CHARGING_THERMISTOR_SUSPEND:
+ case MAX77693_CHARGING_OFF:
+ case MAX77693_CHARGING_OVER_TEMP:
+ case MAX77693_CHARGING_WATCHDOG_EXPIRED:
+ state = POWER_SUPPLY_CHARGE_TYPE_NONE;
+ break;
+ case MAX77693_CHARGING_RESERVED:
+ default:
+ state = POWER_SUPPLY_CHARGE_TYPE_UNKNOWN;
+ }
+
+ return state;
+}
+
+/*
+ * Supported health statuses:
+ * - POWER_SUPPLY_HEALTH_DEAD
+ * - POWER_SUPPLY_HEALTH_GOOD
+ * - POWER_SUPPLY_HEALTH_OVERVOLTAGE
+ * - POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE
+ * - POWER_SUPPLY_HEALTH_UNKNOWN
+ * - POWER_SUPPLY_HEALTH_UNSPEC_FAILURE
+ */
+static int max77693_get_battery_health(struct regmap *regmap)
+{
+ int state;
+ unsigned int data;
+
+ if (regmap_read(regmap, MAX77693_CHG_REG_CHG_DETAILS_01, &data) < 0)
+ return POWER_SUPPLY_HEALTH_UNKNOWN;
+
+ data &= CHG_DETAILS_01_BAT_MASK;
+ data >>= CHG_DETAILS_01_BAT_SHIFT;
+
+ switch (data) {
+ case MAX77693_BATTERY_NOBAT:
+ state = POWER_SUPPLY_HEALTH_DEAD;
+ break;
+ case MAX77693_BATTERY_PREQUALIFICATION:
+ case MAX77693_BATTERY_GOOD:
+ case MAX77693_BATTERY_LOWVOLTAGE:
+ state = POWER_SUPPLY_HEALTH_GOOD;
+ break;
+ case MAX77693_BATTERY_TIMER_EXPIRED:
+ /*
+ * Took longer to charge than expected, charging suspended.
+ * Damaged battery?
+ */
+ state = POWER_SUPPLY_HEALTH_SAFETY_TIMER_EXPIRE;
+ break;
+ case MAX77693_BATTERY_OVERVOLTAGE:
+ state = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
+ break;
+ case MAX77693_BATTERY_OVERCURRENT:
+ state = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
+ break;
+ case MAX77693_BATTERY_RESERVED:
+ default:
+ state = POWER_SUPPLY_HEALTH_UNKNOWN;
+ break;
+ }
+
+ return state;
+}
+
+static int max77693_get_present(struct regmap *regmap)
+{
+ unsigned int data;
+
+ /*
+ * Read CHG_INT_OK register. High DETBAT bit here should be
+ * equal to value 0x0 in CHG_DETAILS_01/BAT field.
+ */
+ regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data);
+ if (data & CHG_INT_OK_DETBAT_MASK)
+ return 0;
+ return 1;
+}
+
+static int max77693_get_online(struct regmap *regmap)
+{
+ unsigned int data;
+
+ regmap_read(regmap, MAX77693_CHG_REG_CHG_INT_OK, &data);
+ if (data & CHG_INT_OK_CHGIN_MASK)
+ return 1;
+ return 0;
+}
+
+static enum power_supply_property max77693_charger_props[] = {
+ POWER_SUPPLY_PROP_STATUS,
+ POWER_SUPPLY_PROP_CHARGE_TYPE,
+ POWER_SUPPLY_PROP_HEALTH,
+ POWER_SUPPLY_PROP_PRESENT,
+ POWER_SUPPLY_PROP_ONLINE,
+ POWER_SUPPLY_PROP_MODEL_NAME,
+ POWER_SUPPLY_PROP_MANUFACTURER,
+};
+
+static int max77693_charger_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct max77693_charger *chg = container_of(psy,
+ struct max77693_charger,
+ charger);
+ struct regmap *regmap = chg->max77693->regmap;
+ int ret = 0;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_STATUS:
+ val->intval = max77693_get_charger_state(regmap);
+ break;
+ case POWER_SUPPLY_PROP_CHARGE_TYPE:
+ val->intval = max77693_get_charge_type(regmap);
+ break;
+ case POWER_SUPPLY_PROP_HEALTH:
+ val->intval = max77693_get_battery_health(regmap);
+ break;
+ case POWER_SUPPLY_PROP_PRESENT:
+ val->intval = max77693_get_present(regmap);
+ break;
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = max77693_get_online(regmap);
+ break;
+ case POWER_SUPPLY_PROP_MODEL_NAME:
+ val->strval = max77693_charger_model;
+ break;
+ case POWER_SUPPLY_PROP_MANUFACTURER:
+ val->strval = max77693_charger_manufacturer;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return ret;
+}
+
+static ssize_t device_attr_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count,
+ int (*fn)(struct max77693_charger *, unsigned long))
+{
+ struct max77693_charger *chg = dev_get_drvdata(dev);
+ unsigned long val;
+ int ret;
+
+ ret = kstrtoul(buf, 10, &val);
+ if (ret)
+ return ret;
+
+ ret = fn(chg, val);
+ if (ret)
+ return ret;
+
+ return count;
+}
+
+static ssize_t fast_charge_timer_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct max77693_charger *chg = dev_get_drvdata(dev);
+ unsigned int data, val;
+ int ret;
+
+ ret = regmap_read(chg->max77693->regmap, MAX77693_CHG_REG_CHG_CNFG_01,
+ &data);
+ if (ret < 0)
+ return ret;
+
+ data &= CHG_CNFG_01_FCHGTIME_MASK;
+ data >>= CHG_CNFG_01_FCHGTIME_SHIFT;
+ switch (data) {
+ case 0x1 ... 0x7:
+ /* Starting from 4 hours, step by 2 hours */
+ val = 4 + (data - 1) * 2;
+ break;
+ case 0x0:
+ default:
+ val = 0;
+ break;
+ }
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static int max77693_set_fast_charge_timer(struct max77693_charger *chg,
+ unsigned long hours)
+{
+ unsigned int data;
+
+ /*
+ * 0x00 - disable
+ * 0x01 - 4h
+ * 0x02 - 6h
+ * ...
+ * 0x07 - 16h
+ * Round down odd values.
+ */
+ switch (hours) {
+ case 4 ... 16:
+ data = (hours - 4) / 2 + 1;
+ break;
+ case 0:
+ /* Disable */
+ data = 0;
+ break;
+ default:
+ return -EINVAL;
+ }
+ data <<= CHG_CNFG_01_FCHGTIME_SHIFT;
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_01,
+ CHG_CNFG_01_FCHGTIME_MASK, data);
+}
+
+static ssize_t fast_charge_timer_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return device_attr_store(dev, attr, buf, count,
+ max77693_set_fast_charge_timer);
+}
+
+static ssize_t top_off_threshold_current_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct max77693_charger *chg = dev_get_drvdata(dev);
+ unsigned int data, val;
+ int ret;
+
+ ret = regmap_read(chg->max77693->regmap, MAX77693_CHG_REG_CHG_CNFG_03,
+ &data);
+ if (ret < 0)
+ return ret;
+
+ data &= CHG_CNFG_03_TOITH_MASK;
+ data >>= CHG_CNFG_03_TOITH_SHIFT;
+
+ if (data <= 0x04)
+ val = 100000 + data * 25000;
+ else
+ val = data * 50000;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static int max77693_set_top_off_threshold_current(struct max77693_charger *chg,
+ unsigned long uamp)
+{
+ unsigned int data;
+
+ if (uamp < 100000 || uamp > 350000)
+ return -EINVAL;
+
+ if (uamp <= 200000)
+ data = (uamp - 100000) / 25000;
+ else
+ /* (200000, 350000> */
+ data = uamp / 50000;
+
+ data <<= CHG_CNFG_03_TOITH_SHIFT;
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_03,
+ CHG_CNFG_03_TOITH_MASK, data);
+}
+
+static ssize_t top_off_threshold_current_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return device_attr_store(dev, attr, buf, count,
+ max77693_set_top_off_threshold_current);
+}
+
+static ssize_t top_off_timer_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct max77693_charger *chg = dev_get_drvdata(dev);
+ unsigned int data, val;
+ int ret;
+
+ ret = regmap_read(chg->max77693->regmap, MAX77693_CHG_REG_CHG_CNFG_03,
+ &data);
+ if (ret < 0)
+ return ret;
+
+ data &= CHG_CNFG_03_TOTIME_MASK;
+ data >>= CHG_CNFG_03_TOTIME_SHIFT;
+
+ val = data * 10;
+
+ return scnprintf(buf, PAGE_SIZE, "%u\n", val);
+}
+
+static int max77693_set_top_off_timer(struct max77693_charger *chg,
+ unsigned long minutes)
+{
+ unsigned int data;
+
+ if (minutes > 70)
+ return -EINVAL;
+
+ data = minutes / 10;
+ data <<= CHG_CNFG_03_TOTIME_SHIFT;
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_03,
+ CHG_CNFG_03_TOTIME_MASK, data);
+}
+
+static ssize_t top_off_timer_store(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ return device_attr_store(dev, attr, buf, count,
+ max77693_set_top_off_timer);
+}
+
+static DEVICE_ATTR_RW(fast_charge_timer);
+static DEVICE_ATTR_RW(top_off_threshold_current);
+static DEVICE_ATTR_RW(top_off_timer);
+
+static int max77693_set_constant_volt(struct max77693_charger *chg,
+ unsigned int uvolt)
+{
+ unsigned int data;
+
+ /*
+ * 0x00 - 3.650 V
+ * 0x01 - 3.675 V
+ * ...
+ * 0x1b - 4.325 V
+ * 0x1c - 4.340 V
+ * 0x1d - 4.350 V
+ * 0x1e - 4.375 V
+ * 0x1f - 4.400 V
+ */
+ if (uvolt >= 3650000 && uvolt < 4340000)
+ data = (uvolt - 3650000) / 25000;
+ else if (uvolt >= 4340000 && uvolt < 4350000)
+ data = 0x1c;
+ else if (uvolt >= 4350000 && uvolt <= 4400000)
+ data = 0x1d + (uvolt - 4350000) / 25000;
+ else {
+ dev_err(chg->dev, "Wrong value for charging constant voltage\n");
+ return -EINVAL;
+ }
+
+ data <<= CHG_CNFG_04_CHGCVPRM_SHIFT;
+
+ dev_dbg(chg->dev, "Charging constant voltage: %u (0x%x)\n", uvolt,
+ data);
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_04,
+ CHG_CNFG_04_CHGCVPRM_MASK, data);
+}
+
+static int max77693_set_min_system_volt(struct max77693_charger *chg,
+ unsigned int uvolt)
+{
+ unsigned int data;
+
+ if (uvolt < 3000000 || uvolt > 3700000) {
+ dev_err(chg->dev, "Wrong value for minimum system regulation voltage\n");
+ return -EINVAL;
+ }
+
+ data = (uvolt - 3000000) / 100000;
+
+ data <<= CHG_CNFG_04_MINVSYS_SHIFT;
+
+ dev_dbg(chg->dev, "Minimum system regulation voltage: %u (0x%x)\n",
+ uvolt, data);
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_04,
+ CHG_CNFG_04_MINVSYS_MASK, data);
+}
+
+static int max77693_set_thermal_regulation_temp(struct max77693_charger *chg,
+ unsigned int cels)
+{
+ unsigned int data;
+
+ switch (cels) {
+ case 70:
+ case 85:
+ case 100:
+ case 115:
+ data = (cels - 70) / 15;
+ break;
+ default:
+ dev_err(chg->dev, "Wrong value for thermal regulation loop temperature\n");
+ return -EINVAL;
+ }
+
+ data <<= CHG_CNFG_07_REGTEMP_SHIFT;
+
+ dev_dbg(chg->dev, "Thermal regulation loop temperature: %u (0x%x)\n",
+ cels, data);
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_07,
+ CHG_CNFG_07_REGTEMP_MASK, data);
+}
+
+static int max77693_set_batttery_overcurrent(struct max77693_charger *chg,
+ unsigned int uamp)
+{
+ unsigned int data;
+
+ if (uamp && (uamp < 2000000 || uamp > 3500000)) {
+ dev_err(chg->dev, "Wrong value for battery overcurrent\n");
+ return -EINVAL;
+ }
+
+ if (uamp)
+ data = ((uamp - 2000000) / 250000) + 1;
+ else
+ data = 0; /* disable */
+
+ data <<= CHG_CNFG_12_B2SOVRC_SHIFT;
+
+ dev_dbg(chg->dev, "Battery overcurrent: %u (0x%x)\n", uamp, data);
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_12,
+ CHG_CNFG_12_B2SOVRC_MASK, data);
+}
+
+static int max77693_set_charge_input_threshold_volt(struct max77693_charger *chg,
+ unsigned int uvolt)
+{
+ unsigned int data;
+
+ switch (uvolt) {
+ case 4300000:
+ data = 0x0;
+ break;
+ case 4700000:
+ case 4800000:
+ case 4900000:
+ data = (uvolt - 4700000) / 100000;
+ default:
+ dev_err(chg->dev, "Wrong value for charge input voltage regulation threshold\n");
+ return -EINVAL;
+ }
+
+ data <<= CHG_CNFG_12_VCHGINREG_SHIFT;
+
+ dev_dbg(chg->dev, "Charge input voltage regulation threshold: %u (0x%x)\n",
+ uvolt, data);
+
+ return regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_12,
+ CHG_CNFG_12_VCHGINREG_MASK, data);
+}
+
+/*
+ * Sets charger registers to proper and safe default values.
+ */
+static int max77693_reg_init(struct max77693_charger *chg)
+{
+ int ret;
+ unsigned int data;
+
+ /* Unlock charger register protection */
+ data = (0x3 << CHG_CNFG_06_CHGPROT_SHIFT);
+ ret = regmap_update_bits(chg->max77693->regmap,
+ MAX77693_CHG_REG_CHG_CNFG_06,
+ CHG_CNFG_06_CHGPROT_MASK, data);
+ if (ret) {
+ dev_err(chg->dev, "Error unlocking registers: %d\n", ret);
+ return ret;
+ }
+
+ ret = max77693_set_fast_charge_timer(chg, DEFAULT_FAST_CHARGE_TIMER);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_top_off_threshold_current(chg,
+ DEFAULT_TOP_OFF_THRESHOLD_CURRENT);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_top_off_timer(chg, DEFAULT_TOP_OFF_TIMER);
+ if (ret)
+ return ret;
+
+ if (!chg->pdata)
+ return 0;
+
+ ret = max77693_set_constant_volt(chg,
+ chg->pdata->constant_volt);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_min_system_volt(chg,
+ chg->pdata->min_system_volt);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_thermal_regulation_temp(chg,
+ chg->pdata->thermal_regulation_temp);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_batttery_overcurrent(chg,
+ chg->pdata->batttery_overcurrent);
+ if (ret)
+ return ret;
+
+ ret = max77693_set_charge_input_threshold_volt(chg,
+ chg->pdata->charge_input_threshold_volt);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+#ifdef CONFIG_OF
+static struct max77693_charger_platform_data *max77693_dt_init(
+ struct device *dev)
+{
+ struct max77693_charger_platform_data *pdata;
+ struct device_node *np = dev->of_node;
+
+ if (!np)
+ return NULL;
+
+ pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);
+ if (!pdata)
+ return NULL;
+
+ if (of_property_read_u32(np, "maxim,constant-microvolt",
+ &pdata->constant_volt))
+ pdata->constant_volt = DEFAULT_CONSTANT_VOLT;
+
+ if (of_property_read_u32(np, "maxim,min-system-microvolt",
+ &pdata->min_system_volt))
+ pdata->min_system_volt = DEFAULT_MIN_SYSTEM_VOLT;
+
+ if (of_property_read_u32(np, "maxim,thermal-regulation-celsius",
+ &pdata->thermal_regulation_temp))
+ pdata->thermal_regulation_temp = DEFAULT_THERMAL_REGULATION_TEMP;
+
+ if (of_property_read_u32(np, "maxim,battery-overcurrent-microamp",
+ &pdata->batttery_overcurrent))
+ pdata->batttery_overcurrent = DEFAULT_BATTERY_OVERCURRENT;
+
+ if (of_property_read_u32(np, "maxim,charge-input-threshold-microvolt",
+ &pdata->charge_input_threshold_volt))
+ pdata->charge_input_threshold_volt =
+ DEFAULT_CHARGER_INPUT_THRESHOLD_VOLT;
+
+ return pdata;
+}
+#else /* CONFIG_OF */
+static struct max77693_charger_platform_data *max77693_dt_init(
+ struct device *dev)
+{
+ return NULL;
+}
+#endif /* CONFIG_OF */
+
+static int max77693_charger_probe(struct platform_device *pdev)
+{
+ struct max77693_charger *chg;
+ struct max77693_dev *max77693 = dev_get_drvdata(pdev->dev.parent);
+ int ret;
+
+ chg = devm_kzalloc(&pdev->dev, sizeof(*chg), GFP_KERNEL);
+ if (!chg)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, chg);
+ chg->dev = &pdev->dev;
+ chg->max77693 = max77693;
+
+ chg->pdata = max77693_dt_init(&pdev->dev);
+
+ ret = max77693_reg_init(chg);
+ if (ret)
+ return ret;
+
+ chg->charger.name = max77693_charger_name;
+ chg->charger.type = POWER_SUPPLY_TYPE_BATTERY;
+ chg->charger.properties = max77693_charger_props;
+ chg->charger.num_properties = ARRAY_SIZE(max77693_charger_props);
+ chg->charger.get_property = max77693_charger_get_property;
+
+ ret = device_create_file(&pdev->dev, &dev_attr_fast_charge_timer);
+ if (ret) {
+ dev_err(&pdev->dev, "failed: create fast charge timer sysfs entry\n");
+ goto err;
+ }
+
+ ret = device_create_file(&pdev->dev,
+ &dev_attr_top_off_threshold_current);
+ if (ret) {
+ dev_err(&pdev->dev, "failed: create top off current sysfs entry\n");
+ goto err;
+ }
+
+ ret = device_create_file(&pdev->dev, &dev_attr_top_off_timer);
+ if (ret) {
+ dev_err(&pdev->dev, "failed: create top off timer sysfs entry\n");
+ goto err;
+ }
+
+ ret = power_supply_register(&pdev->dev, &chg->charger);
+ if (ret) {
+ dev_err(&pdev->dev, "failed: power supply register\n");
+ goto err;
+ }
+
+ return 0;
+
+err:
+ device_remove_file(&pdev->dev, &dev_attr_top_off_timer);
+ device_remove_file(&pdev->dev, &dev_attr_top_off_threshold_current);
+ device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer);
+
+ return ret;
+}
+
+static int max77693_charger_remove(struct platform_device *pdev)
+{
+ struct max77693_charger *chg = platform_get_drvdata(pdev);
+
+ device_remove_file(&pdev->dev, &dev_attr_top_off_timer);
+ device_remove_file(&pdev->dev, &dev_attr_top_off_threshold_current);
+ device_remove_file(&pdev->dev, &dev_attr_fast_charge_timer);
+
+ power_supply_unregister(&chg->charger);
+
+ return 0;
+}
+
+static const struct platform_device_id max77693_charger_id[] = {
+ { "max77693-charger", 0, },
+ { }
+};
+MODULE_DEVICE_TABLE(platform, max77693_charger_id);
+
+static struct platform_driver max77693_charger_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "max77693-charger",
+ },
+ .probe = max77693_charger_probe,
+ .remove = max77693_charger_remove,
+ .id_table = max77693_charger_id,
+};
+module_platform_driver(max77693_charger_driver);
+
+MODULE_AUTHOR("Krzysztof Kozlowski <k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>");
+MODULE_DESCRIPTION("Maxim 77693 charger driver");
+MODULE_LICENSE("GPL");
--
1.9.1
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH v2 3/5] mfd: max77693: Add defines for MAX77693 charger driver
From: Krzysztof Kozlowski @ 2014-10-20 12:34 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
linux-kernel, linux-pm, Samuel Ortiz, Lee Jones, linux-api,
devicetree
Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
Krzysztof Kozlowski
In-Reply-To: <1413808489-3524-1-git-send-email-k.kozlowski@samsung.com>
Prepare for adding support for Maxim 77693 charger by adding necessary
new defines and structure for device tree parsed data.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
Acked-by: Lee Jones <lee.jones@linaro.org>
---
include/linux/mfd/max77693-private.h | 108 +++++++++++++++++++++++++++++++++++
include/linux/mfd/max77693.h | 8 +++
2 files changed, 116 insertions(+)
diff --git a/include/linux/mfd/max77693-private.h b/include/linux/mfd/max77693-private.h
index fc17d56581b2..e1b2b61285b9 100644
--- a/include/linux/mfd/max77693-private.h
+++ b/include/linux/mfd/max77693-private.h
@@ -144,10 +144,118 @@ enum max77693_pmic_reg {
#define FLASH_INT_FLED1_SHORT BIT(3)
#define FLASH_INT_OVER_CURRENT BIT(4)
+/* Fast charge timer in in hours */
+#define DEFAULT_FAST_CHARGE_TIMER 4
+/* microamps */
+#define DEFAULT_TOP_OFF_THRESHOLD_CURRENT 150000
+/* minutes */
+#define DEFAULT_TOP_OFF_TIMER 30
+/* microvolts */
+#define DEFAULT_CONSTANT_VOLT 4200000
+/* microvolts */
+#define DEFAULT_MIN_SYSTEM_VOLT 3600000
+/* celsius */
+#define DEFAULT_THERMAL_REGULATION_TEMP 100
+/* microamps */
+#define DEFAULT_BATTERY_OVERCURRENT 3500000
+/* microvolts */
+#define DEFAULT_CHARGER_INPUT_THRESHOLD_VOLT 4300000
+
+/* MAX77693_CHG_REG_CHG_INT_OK register */
+#define CHG_INT_OK_BYP_SHIFT 0
+#define CHG_INT_OK_BAT_SHIFT 3
+#define CHG_INT_OK_CHG_SHIFT 4
+#define CHG_INT_OK_CHGIN_SHIFT 6
+#define CHG_INT_OK_DETBAT_SHIFT 7
+#define CHG_INT_OK_BYP_MASK BIT(CHG_INT_OK_BYP_SHIFT)
+#define CHG_INT_OK_BAT_MASK BIT(CHG_INT_OK_BAT_SHIFT)
+#define CHG_INT_OK_CHG_MASK BIT(CHG_INT_OK_CHG_SHIFT)
+#define CHG_INT_OK_CHGIN_MASK BIT(CHG_INT_OK_CHGIN_SHIFT)
+#define CHG_INT_OK_DETBAT_MASK BIT(CHG_INT_OK_DETBAT_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_DETAILS_00 register */
+#define CHG_DETAILS_00_CHGIN_SHIFT 5
+#define CHG_DETAILS_00_CHGIN_MASK (0x3 << CHG_DETAILS_00_CHGIN_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_DETAILS_01 register */
+#define CHG_DETAILS_01_CHG_SHIFT 0
+#define CHG_DETAILS_01_BAT_SHIFT 4
+#define CHG_DETAILS_01_TREG_SHIFT 7
+#define CHG_DETAILS_01_CHG_MASK (0xf << CHG_DETAILS_01_CHG_SHIFT)
+#define CHG_DETAILS_01_BAT_MASK (0x7 << CHG_DETAILS_01_BAT_SHIFT)
+#define CHG_DETAILS_01_TREG_MASK BIT(7)
+
+/* MAX77693_CHG_REG_CHG_DETAILS_01/CHG field */
+enum max77693_charger_charging_state {
+ MAX77693_CHARGING_PREQUALIFICATION = 0x0,
+ MAX77693_CHARGING_FAST_CONST_CURRENT,
+ MAX77693_CHARGING_FAST_CONST_VOLTAGE,
+ MAX77693_CHARGING_TOP_OFF,
+ MAX77693_CHARGING_DONE,
+ MAX77693_CHARGING_HIGH_TEMP,
+ MAX77693_CHARGING_TIMER_EXPIRED,
+ MAX77693_CHARGING_THERMISTOR_SUSPEND,
+ MAX77693_CHARGING_OFF,
+ MAX77693_CHARGING_RESERVED,
+ MAX77693_CHARGING_OVER_TEMP,
+ MAX77693_CHARGING_WATCHDOG_EXPIRED,
+};
+
+/* MAX77693_CHG_REG_CHG_DETAILS_01/BAT field */
+enum max77693_charger_battery_state {
+ MAX77693_BATTERY_NOBAT = 0x0,
+ /* Dead-battery or low-battery prequalification */
+ MAX77693_BATTERY_PREQUALIFICATION,
+ MAX77693_BATTERY_TIMER_EXPIRED,
+ MAX77693_BATTERY_GOOD,
+ MAX77693_BATTERY_LOWVOLTAGE,
+ MAX77693_BATTERY_OVERVOLTAGE,
+ MAX77693_BATTERY_OVERCURRENT,
+ MAX77693_BATTERY_RESERVED,
+};
+
+/* MAX77693_CHG_REG_CHG_DETAILS_02 register */
+#define CHG_DETAILS_02_BYP_SHIFT 0
+#define CHG_DETAILS_02_BYP_MASK (0xf << CHG_DETAILS_02_BYP_SHIFT)
+
/* MAX77693 CHG_CNFG_00 register */
#define CHG_CNFG_00_CHG_MASK 0x1
#define CHG_CNFG_00_BUCK_MASK 0x4
+/* MAX77693_CHG_REG_CHG_CNFG_01 register */
+#define CHG_CNFG_01_FCHGTIME_SHIFT 0
+#define CHG_CNFG_01_CHGRSTRT_SHIFT 4
+#define CHG_CNFG_01_PQEN_SHIFT 7
+#define CHG_CNFG_01_FCHGTIME_MASK (0x7 << CHG_CNFG_01_FCHGTIME_SHIFT)
+#define CHG_CNFG_01_CHGRSTRT_MASK (0x3 << CHG_CNFG_01_CHGRSTRT_SHIFT)
+#define CHG_CNFG_01_PQEN_MAKS BIT(CHG_CNFG_01_PQEN_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_CNFG_03 register */
+#define CHG_CNFG_03_TOITH_SHIFT 0
+#define CHG_CNFG_03_TOTIME_SHIFT 3
+#define CHG_CNFG_03_TOITH_MASK (0x7 << CHG_CNFG_03_TOITH_SHIFT)
+#define CHG_CNFG_03_TOTIME_MASK (0x7 << CHG_CNFG_03_TOTIME_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_CNFG_04 register */
+#define CHG_CNFG_04_CHGCVPRM_SHIFT 0
+#define CHG_CNFG_04_MINVSYS_SHIFT 5
+#define CHG_CNFG_04_CHGCVPRM_MASK (0x1f << CHG_CNFG_04_CHGCVPRM_SHIFT)
+#define CHG_CNFG_04_MINVSYS_MASK (0x7 << CHG_CNFG_04_MINVSYS_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_CNFG_06 register */
+#define CHG_CNFG_06_CHGPROT_SHIFT 2
+#define CHG_CNFG_06_CHGPROT_MASK (0x3 << CHG_CNFG_06_CHGPROT_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_CNFG_07 register */
+#define CHG_CNFG_07_REGTEMP_SHIFT 5
+#define CHG_CNFG_07_REGTEMP_MASK (0x3 << CHG_CNFG_07_REGTEMP_SHIFT)
+
+/* MAX77693_CHG_REG_CHG_CNFG_12 register */
+#define CHG_CNFG_12_B2SOVRC_SHIFT 0
+#define CHG_CNFG_12_VCHGINREG_SHIFT 3
+#define CHG_CNFG_12_B2SOVRC_MASK (0x7 << CHG_CNFG_12_B2SOVRC_SHIFT)
+#define CHG_CNFG_12_VCHGINREG_MASK (0x3 << CHG_CNFG_12_VCHGINREG_SHIFT)
+
/* MAX77693 CHG_CNFG_09 Register */
#define CHG_CNFG_09_CHGIN_ILIM_MASK 0x7F
diff --git a/include/linux/mfd/max77693.h b/include/linux/mfd/max77693.h
index f0b6585cd874..88ef24b28294 100644
--- a/include/linux/mfd/max77693.h
+++ b/include/linux/mfd/max77693.h
@@ -63,6 +63,14 @@ struct max77693_muic_platform_data {
int path_uart;
};
+struct max77693_charger_platform_data {
+ u32 constant_volt;
+ u32 min_system_volt;
+ u32 thermal_regulation_temp;
+ u32 batttery_overcurrent;
+ u32 charge_input_threshold_volt;
+};
+
/* MAX77693 led flash */
/* triggers */
--
1.9.1
^ permalink raw reply related
* [PATCH v2 2/5] mfd: max77693: Map charger device to its own of_node
From: Krzysztof Kozlowski @ 2014-10-20 12:34 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
linux-kernel, linux-pm, Samuel Ortiz, Lee Jones, linux-api,
devicetree
Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
Krzysztof Kozlowski
In-Reply-To: <1413808489-3524-1-git-send-email-k.kozlowski@samsung.com>
Add a "maxim,max77693-charger" of_compatible to the mfd_cell so the MFD
child device (the charger) will have its own of_node set. This will be
used by the max77693 charger driver in next patches to obtain battery
configuration from DTS.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski@samsung.com>
---
drivers/mfd/max77693.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/mfd/max77693.c b/drivers/mfd/max77693.c
index cf008f45968c..2277a11b6629 100644
--- a/drivers/mfd/max77693.c
+++ b/drivers/mfd/max77693.c
@@ -43,7 +43,10 @@
static const struct mfd_cell max77693_devs[] = {
{ .name = "max77693-pmic", },
- { .name = "max77693-charger", },
+ {
+ .name = "max77693-charger",
+ .of_compatible = "maxim,max77693-charger",
+ },
{ .name = "max77693-muic", },
{ .name = "max77693-haptic", },
{
--
1.9.1
^ permalink raw reply related
* [PATCH v2 1/5] devicetree: mfd: max77693: Document new bindings for charger
From: Krzysztof Kozlowski @ 2014-10-20 12:34 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA, Samuel Ortiz, Lee Jones,
linux-api-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
Krzysztof Kozlowski
In-Reply-To: <1413808489-3524-1-git-send-email-k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
Document new device tree bindings for Maxim 77693 charger driver.
Signed-off-by: Krzysztof Kozlowski <k.kozlowski-Sze3O3UU22JBDgjK7y7TUQ@public.gmane.org>
---
Documentation/devicetree/bindings/mfd/max77693.txt | 46 ++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/Documentation/devicetree/bindings/mfd/max77693.txt b/Documentation/devicetree/bindings/mfd/max77693.txt
index 11921cc417bf..d0c3d787df12 100644
--- a/Documentation/devicetree/bindings/mfd/max77693.txt
+++ b/Documentation/devicetree/bindings/mfd/max77693.txt
@@ -27,6 +27,42 @@ Optional properties:
[*] refer Documentation/devicetree/bindings/regulator/regulator.txt
+- charger : Node configuring the charger driver.
+ If present, required properties:
+ - compatible : Must be "maxim,max77693-charger".
+
+ Optional properties (if not set, defaults will be used):
+ - maxim,constant-microvolt : Battery constant voltage in uV. The charger
+ will operate in fast charge constant current mode till battery voltage
+ reaches this level. Then the charger will switch to fast charge constant
+ voltage mode. Also vsys (system voltage) will be set to this value when
+ DC power is supplied but charger is not enabled.
+ Valid values: 3650000 - 4400000, step by 25000 (rounded down)
+ Default: 4200000
+
+ - maxim,min-system-microvolt : Minimal system voltage in uV.
+ Valid values: 3000000 - 3700000, step by 100000 (rounded down)
+ Default: 3600000
+
+ - maxim,thermal-regulation-celsius : Temperature in Celsius for entering
+ high temperature charging mode. If die temperature exceeds this value
+ the charging current will be reduced by 105 mA/Celsius.
+ Valid values: 70, 85, 100, 115
+ Default: 100
+
+ - maxim,battery-overcurrent-microamp : Overcurrent protection threshold
+ in uA (current from battery to system).
+ Valid values: 2000000 - 3500000, step by 250000 (rounded down)
+ Default: 3500000
+
+ - maxim,charge-input-threshold-microvolt : Threshold voltage in uV for
+ triggering input voltage regulation loop. If input voltage decreases
+ below this value, the input current will be reduced to reach the
+ threshold voltage.
+ Valid values: 4300000, 4700000, 4800000, 4900000
+ Default: 4300000
+
+
Example:
max77693@66 {
compatible = "maxim,max77693";
@@ -52,4 +88,14 @@ Example:
regulator-boot-on;
};
};
+
+ charger {
+ compatible = "maxim,max77693-charger";
+
+ maxim,constant-microvolt = <4200000>;
+ maxim,min-system-microvolt = <3600000>;
+ maxim,thermal-regulation-celsius = <75>;
+ maxim,battery-overcurrent-microamp = <3000000>;
+ maxim,charge-input-threshold-microvolt = <4300000>;
+ };
};
--
1.9.1
^ permalink raw reply related
* [PATCH v2 0/5] power/mfd: Add max77693 charger driver
From: Krzysztof Kozlowski @ 2014-10-20 12:34 UTC (permalink / raw)
To: Sebastian Reichel, Dmitry Eremin-Solenikov, David Woodhouse,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-pm-u79uwXL29TY76Z2rM5mHXA, Samuel Ortiz, Lee Jones,
linux-api-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
Cc: Kyungmin Park, Marek Szyprowski, Bartlomiej Zolnierkiewicz,
Krzysztof Kozlowski
Hi,
Changes since v1
================
1. Add patch 2/5: mfd: max77693: Map charger device to its own of_node
(forgot to send it in v1)
2. Remove patches for DTS and configs. I'll send them later.
3. Add ack from Lee Jones (patch 3/5).
Description
===========
The patchset adds max77693 charger driver present on Trats2 board
(and Galaxy S III). The driver configures battery charger and exposes
power supply interface.
Driver is necessary to provide full charging stack on Trats2 device
(extcon, charger-manager etc.).
Everything rebased on next-20141020.
Best regards,
Krzysztof
Krzysztof Kozlowski (5):
devicetree: mfd: max77693: Document new bindings for charger
mfd: max77693: Map charger device to its own of_node
mfd: max77693: Add defines for MAX77693 charger driver
power: max77693: Add charger driver for Maxim 77693
Documentation: charger: max77693: Document exported sysfs entry
Documentation/ABI/testing/sysfs-class-power | 42 ++
Documentation/devicetree/bindings/mfd/max77693.txt | 46 ++
drivers/mfd/max77693.c | 5 +-
drivers/power/Kconfig | 6 +
drivers/power/Makefile | 1 +
drivers/power/max77693_charger.c | 763 +++++++++++++++++++++
include/linux/mfd/max77693-private.h | 108 +++
include/linux/mfd/max77693.h | 8 +
8 files changed, 978 insertions(+), 1 deletion(-)
create mode 100644 drivers/power/max77693_charger.c
--
1.9.1
^ permalink raw reply
* Re: [PATCH v11 0/3] Add drm driver for Rockchip Socs
From: Heiko Stübner @ 2014-10-20 11:45 UTC (permalink / raw)
To: Mark yao
Cc: Dave Airlie, Boris BREZILLON, Rob Clark, Daniel Vetter,
Rob Herring, Pawel Moll, Mark Rutland, Ian Campbell, Kumar Gala,
Randy Dunlap, Grant Likely, Greg Kroah-Hartman, John Stultz,
Rom Lemarchand,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-doc-u79uwXL29TY76Z2rM5mHXA, LKML, dri-devel,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-rockchip-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
dianders-F7+t8E8rja9g9hUCZPvPmw, Stéphane Marchesin,
dbehr-F7+t8E8rja9g9hUCZPvPmw
In-Reply-To: <5440D68E.4070103-TNX95d0MmH7DzftRWevZcw@public.gmane.org>
Hi Mark,
Am Freitag, 17. Oktober 2014, 16:42:54 schrieb Mark yao:
> On 2014年10月17日 16:25, Heiko Stübner wrote:
> > Am Freitag, 17. Oktober 2014, 16:16:01 schrieb Mark yao:
> >> On 2014年10月17日 14:24, Heiko Stübner wrote:
> >>> Hi Mark,
> >>>
> >>> Am Freitag, 17. Oktober 2014, 12:22:53 schrieb Mark yao:
> >>>> On 2014年10月17日 08:46, Dave Airlie wrote:
> >>>>> On 17 October 2014 10:40, Mark yao <mark.yao-TNX95d0MmH7DzftRWevZcw@public.gmane.org> wrote:
> >>>>>> Hi
> >>>>>> I think Rockchip drm driver is ready now, can it land?
> >>>>>
> >>>>> I probably want to wait until -rc1 though I suppose since its a new
> >>>>> driver and self contained we might be able to see if Linus is
> >>>>> interested in squeezing it in.
> >>>>>
> >>>>> Can you send me a git pull request for it against drm-next or even
> >>>>> 3.17.
> >>>>>
> >>>>> Dave.
> >>>>
> >>>> Hi, Dave
> >>>>
> >>>> the git pull request:
> >>>> The following changes since commit
> >
> > 4db36870b92cdf5a79615aeabc68efc97df13918:
> >>> I think this needs a fix. Your commit 4db36870b is the pending iommu
> >>> driver. Which isn't part of neither the mainline kernel nor the drm tree
> >>> Dave meant.
> >>>
> >>> What Dave meant was to base your patches on top of his "drm-next" branch
> >>> or
> >>> the raw 3.17 release.
> >>>
> >>> So either base the branch on drm-next from
> >>>
> >>> http://cgit.freedesktop.org/~airlied/linux/log/?h=drm-next
> >>>
> >>> or the 3.17 release tag from Linus Torvalds. Apply your patches on top
> >>> and
> >>> create pull from there.
> >>>
> >>> I've just checked ... your drm patches apply cleanly against 3.17, so
> >>> your
> >>> branch to be pulled should probably look something like
> >>>
> >>> https://github.com/mmind/linux-rockchip/commits/tmp/drmtest
> >>>
> >>> Heiko
> >>
> >> Hi Heiko
> >>
> >> thanks for you check.
> >>
> >> Hi Dave
> >>
> >> I have reupload a branch cleanly against 3.17:
> > sorry, but I think this might need another round.
> >
> > Your current base commit 0429fbc0bdc2 is already part of the current 3.18
> > merge window - which Dave won't have in his tree I guess. The commit you
> > should base your patches on is bfe01a5ba249 - the 3.17 release.
> >
> > Simply do a
> >
> > git checkout v3.17
> > git checkout -b drmupstream
> >
> > apply your patches and send the pull request with v3.17 as base.
> >
> >
> > Heiko
>
> I think that would be ok:
yes the pull request itself looks ok, but you may have to be more explicit.
Normally a pull request mail should have its own subject and body and not
be embedded somewhere into the response thread. This enables the
maintainers to see what they're asked to do easily.
So I guess it would be better to compose a separate mail, with a correct
subject, somewhat similar to [0] for example.
Heiko
[0] http://www.spinics.net/lists/arm-kernel/msg366129.html
----- 8< ----------------
Subject: [GIT PULL] core drm support for Rockchip SoCs
The following changes since commit bfe01a5ba2490f299e1d2d5508cbbbadd897bbe9:
Linux 3.17 (2014-10-05 12:23:04 -0700)
are available in the git repository at:
https://github.com/markyzq/kernel-drm-rockchip.git drmrockchip
for you to fetch changes up to 45bb5f4e7e82b30e9e7069c73441413680c9a59f:
dt-bindings: video: Add documentation for rockchip vop (2014-10-17
16:39:31 +0800)
----------------------------------------------------------------
Mark yao (3):
drm: rockchip: Add basic drm driver
dt-bindings: video: Add for rockchip display subsytem
dt-bindings: video: Add documentation for rockchip vop
.../devicetree/bindings/video/rockchip-drm.txt | 19 +
.../devicetree/bindings/video/rockchip-vop.txt | 58 +
drivers/gpu/drm/Kconfig | 2 +
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/rockchip/Kconfig | 17 +
drivers/gpu/drm/rockchip/Makefile | 8 +
drivers/gpu/drm/rockchip/rockchip_drm_drv.c | 449 ++++++
drivers/gpu/drm/rockchip/rockchip_drm_drv.h | 54 +
drivers/gpu/drm/rockchip/rockchip_drm_fb.c | 200 +++
drivers/gpu/drm/rockchip/rockchip_drm_fb.h | 28 +
drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c | 210 +++
drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h | 20 +
drivers/gpu/drm/rockchip/rockchip_drm_gem.c | 293 ++++
drivers/gpu/drm/rockchip/rockchip_drm_gem.h | 54 +
drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 1427 ++++++++++++++++++++
drivers/gpu/drm/rockchip/rockchip_drm_vop.h | 196 +++
16 files changed, 3036 insertions(+)
create mode 100644 Documentation/devicetree/bindings/video/rockchip-drm.txt
create mode 100644 Documentation/devicetree/bindings/video/rockchip-vop.txt
create mode 100644 drivers/gpu/drm/rockchip/Kconfig
create mode 100644 drivers/gpu/drm/rockchip/Makefile
create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_drv.c
create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_drv.h
create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_fb.c
create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_fb.h
create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c
create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h
create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_gem.c
create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_gem.h
create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop.c
create mode 100644 drivers/gpu/drm/rockchip/rockchip_drm_vop.h
^ permalink raw reply
* Re: [PATCH v3 4/6] tpm: TPM 2.0 sysfs attributes
From: Jarkko Sakkinen @ 2014-10-20 10:45 UTC (permalink / raw)
To: Tomas Winkler
Cc: Greg KH, Peter Huewe, Ashley Lai, Marcel Selhorst,
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-api-u79uwXL29TY76Z2rM5mHXA,
josh.triplett-ral2JQCrhuEAvxtiuMwx3w,
christophe.ricard-Re5JQEeQqe8AvxtiuMwx3w,
will.c.arthur-ral2JQCrhuEAvxtiuMwx3w,
monty.wiseman-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <CA+i0qc4XgqF4c+TcyXvPG6XFs_LNvWWRs8p_=-iGeD_bQU9Zpw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Mon, Oct 20, 2014 at 12:09:27AM +0300, Tomas Winkler wrote:
> >
> > Here the options are limited because misc_register already spawns
> > KOBJ_ADD. Not much to do unless we would wipe the current use of
> > misc driver completely.
>
> I would strongly recommend to drop the misc layer here, as tpm itself
> can provide the needed abstraction for the devices.
This is exactly what I'm going to do for v4 of the patch set and take
the rtc subsystem as a guideline how to structure things in proper way.
It is ABI break but if you look at the TPM1 sysfs attributes most of
them haven't been ever machine readable anyway so I'll at least give it
shot and a take the feedback. I'm fully aware that doing such thing is
comparable to killing your own mother :)
Past experiences of trying to do such thing [1] have not been succesful
but on the other hand this is very different scenario and different user
volumes.
It would make sense to rip off all the "human-only" TPM1 attributes in
the same round. I'm wondering what is the set of sysfs attributes is
that TrouSerS is dependent of? I would suggest to leave that subset
available and remove attributes such as 'pcrs' that breaks all the
conventions.
[1] http://lwn.net/Articles/172306/
/Jarkko
^ permalink raw reply
* Re: [PATCH v3 4/6] tpm: TPM 2.0 sysfs attributes
From: Jarkko Sakkinen @ 2014-10-20 10:35 UTC (permalink / raw)
To: Andy Lutomirski
Cc: Peter Huewe, Ashley Lai, Marcel Selhorst,
tpmdd-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Linux API,
josh.triplett-ral2JQCrhuEAvxtiuMwx3w,
christophe.ricard-Re5JQEeQqe8AvxtiuMwx3w,
will.c.arthur-ral2JQCrhuEAvxtiuMwx3w,
monty.wiseman-ral2JQCrhuEAvxtiuMwx3w
In-Reply-To: <CALCETrUt8wK+wPULZpPQks3xEB0JkQkUD=peLSnBrMo70LT13w-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
On Sun, Oct 19, 2014 at 03:07:49PM -0700, Andy Lutomirski wrote:
> On Wed, Oct 15, 2014 at 4:35 AM, Jarkko Sakkinen
> <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote:
> > Implemented sysfs attributes for TPM2 devices. TPM2 sysfs attributes
> > are mounted in the actual device associated with the chip instead of
> > platform device like with TPM1 devices.
> >
> > Documentation/ABI/stable/sysfs-class/tpm2 contains descriptions
> > of these attributes.
> >
> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
>
>
> > +What: /sys/class/misc/tpmX/device/cancel
> > +Date: October 2014
> > +KernelVersion: 3.19
> > +Contact: tpmdd-devel-TtF/mJH4Jtrk1uMJSBkQmQ@public.gmane.org
> > +Description: The "cancel" property allows you to cancel the currently
> > + pending TPM command. Writing any value to cancel will call the
> > + TPM chip specific cancel operation.
>
> This is weird. From the POV of a sysfs user, what operation gets
> canceled? What if it's a kernel-internal operation?
>
> Shouldn't this be an ioctl?
This was a really good insight, thank you. I just followed along the
lines what was defined for TPM1 but didn't think too much. This is
racy attribute and should not be added for TPM2.
I'll drop this. Adding ioctl() later would much better idea as it is
not racy but I think it should be postponed after this patch set so
that it stays digestable size.
> --Andy
/Jarkko
^ permalink raw reply
* [PATCH v17 7/7] mm: Don't split THP page when syscall is called
From: Minchan Kim @ 2014-10-20 10:12 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Michael Kerrisk, linux-api, Hugh Dickins,
Johannes Weiner, Rik van Riel, KOSAKI Motohiro, Mel Gorman,
Jason Evans, zhangyanfei, Kirill A. Shutemov, Minchan Kim,
Andrea Arcangeli, Kirill A. Shutemov
In-Reply-To: <1413799924-17946-1-git-send-email-minchan@kernel.org>
We don't need to split THP page when MADV_FREE syscall is
called. It could be done when VM decide really frees it so
we could avoid unnecessary THP split.
Cc: Andrea Arcangeli <aarcange@redhat.com>
Acked-by: Rik van Riel <riel@redhat.com>
Acked-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
include/linux/huge_mm.h | 4 ++++
mm/huge_memory.c | 35 +++++++++++++++++++++++++++++++++++
mm/madvise.c | 21 ++++++++++++++++++++-
mm/rmap.c | 8 ++++++--
mm/vmscan.c | 28 ++++++++++++++++++----------
5 files changed, 83 insertions(+), 13 deletions(-)
diff --git a/include/linux/huge_mm.h b/include/linux/huge_mm.h
index ad9051bab267..07f736b18ffc 100644
--- a/include/linux/huge_mm.h
+++ b/include/linux/huge_mm.h
@@ -19,6 +19,9 @@ extern struct page *follow_trans_huge_pmd(struct vm_area_struct *vma,
unsigned long addr,
pmd_t *pmd,
unsigned int flags);
+extern int madvise_free_huge_pmd(struct mmu_gather *tlb,
+ struct vm_area_struct *vma,
+ pmd_t *pmd, unsigned long addr);
extern int zap_huge_pmd(struct mmu_gather *tlb,
struct vm_area_struct *vma,
pmd_t *pmd, unsigned long addr);
@@ -56,6 +59,7 @@ extern pmd_t *page_check_address_pmd(struct page *page,
unsigned long address,
enum page_check_address_pmd_flag flag,
spinlock_t **ptl);
+extern int pmd_freeable(pmd_t pmd);
#define HPAGE_PMD_ORDER (HPAGE_PMD_SHIFT-PAGE_SHIFT)
#define HPAGE_PMD_NR (1<<HPAGE_PMD_ORDER)
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index de984159cf0b..5be0a5f3ea3a 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1384,6 +1384,36 @@ out:
return 0;
}
+int madvise_free_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
+ pmd_t *pmd, unsigned long addr)
+
+{
+ spinlock_t *ptl;
+ struct mm_struct *mm = tlb->mm;
+ int ret = 1;
+
+ if (pmd_trans_huge_lock(pmd, vma, &ptl) == 1) {
+ struct page *page;
+ pmd_t orig_pmd;
+
+ orig_pmd = pmdp_get_and_clear(mm, addr, pmd);
+
+ /* No hugepage in swapcache */
+ page = pmd_page(orig_pmd);
+ VM_BUG_ON_PAGE(PageSwapCache(page), page);
+
+ orig_pmd = pmd_mkold(orig_pmd);
+ orig_pmd = pmd_mkclean(orig_pmd);
+
+ set_pmd_at(mm, addr, pmd, orig_pmd);
+ tlb_remove_pmd_tlb_entry(tlb, pmd, addr);
+ spin_unlock(ptl);
+ ret = 0;
+ }
+
+ return ret;
+}
+
int zap_huge_pmd(struct mmu_gather *tlb, struct vm_area_struct *vma,
pmd_t *pmd, unsigned long addr)
{
@@ -1620,6 +1650,11 @@ unlock:
return NULL;
}
+int pmd_freeable(pmd_t pmd)
+{
+ return !pmd_dirty(pmd);
+}
+
static int __split_huge_page_splitting(struct page *page,
struct vm_area_struct *vma,
unsigned long address)
diff --git a/mm/madvise.c b/mm/madvise.c
index a21584235bb6..84badee5f46d 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -271,8 +271,26 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
spinlock_t *ptl;
pte_t *pte, ptent;
struct page *page;
+ unsigned long next;
+
+ next = pmd_addr_end(addr, end);
+ if (pmd_trans_huge(*pmd)) {
+ if (next - addr != HPAGE_PMD_SIZE) {
+#ifdef CONFIG_DEBUG_VM
+ if (!rwsem_is_locked(&mm->mmap_sem)) {
+ pr_err("%s: mmap_sem is unlocked! addr=0x%lx end=0x%lx vma->vm_start=0x%lx vma->vm_end=0x%lx\n",
+ __func__, addr, end,
+ vma->vm_start,
+ vma->vm_end);
+ BUG();
+ }
+#endif
+ split_huge_page_pmd(vma, addr, pmd);
+ } else if (!madvise_free_huge_pmd(tlb, vma, pmd, addr))
+ goto next;
+ /* fall through */
+ }
- split_huge_page_pmd(vma, addr, pmd);
if (pmd_trans_unstable(pmd))
return 0;
@@ -316,6 +334,7 @@ static int madvise_free_pte_range(pmd_t *pmd, unsigned long addr,
}
arch_leave_lazy_mmu_mode();
pte_unmap_unlock(pte - 1, ptl);
+next:
cond_resched();
return 0;
}
diff --git a/mm/rmap.c b/mm/rmap.c
index 93149c82a5a4..3a7081d884b9 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -704,9 +704,13 @@ static int page_referenced_one(struct page *page, struct vm_area_struct *vma,
referenced++;
/*
- * In this implmentation, MADV_FREE doesn't support THP free
+ * Use pmd_freeable instead of raw pmd_dirty because in some
+ * of architecture, pmd_dirty is not defined unless
+ * CONFIG_TRANSPARNTE_HUGE is enabled
*/
- dirty++;
+ if (!pmd_freeable(*pmd))
+ dirty++;
+
spin_unlock(ptl);
} else {
pte_t *pte;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 8f67765ebb77..29ae6382275a 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -976,17 +976,25 @@ static unsigned long shrink_page_list(struct list_head *page_list,
* Anonymous process memory has backing store?
* Try to allocate it some swap space here.
*/
- if (PageAnon(page) && !PageSwapCache(page) && !freeable) {
- if (!(sc->gfp_mask & __GFP_IO))
- goto keep_locked;
- if (!add_to_swap(page, page_list))
- goto activate_locked;
- may_enter_fs = 1;
-
- /* Adding to swap updated mapping */
- mapping = page_mapping(page);
+ if (PageAnon(page) && !PageSwapCache(page)) {
+ if (!freeable) {
+ if (!(sc->gfp_mask & __GFP_IO))
+ goto keep_locked;
+ if (!add_to_swap(page, page_list))
+ goto activate_locked;
+ may_enter_fs = 1;
+ /* Adding to swap updated mapping */
+ mapping = page_mapping(page);
+ } else {
+ if (likely(!PageTransHuge(page)))
+ goto unmap;
+ /* try_to_unmap isn't aware of THP page */
+ if (unlikely(split_huge_page_to_list(page,
+ page_list)))
+ goto keep_locked;
+ }
}
-
+unmap:
/*
* The page is mapped into the page tables of one or more
* processes. Try to unmap it here.
--
2.0.0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v17 6/7] arm64: add pmd_[dirty|mkclean] for THP
From: Minchan Kim @ 2014-10-20 10:12 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Michael Kerrisk, linux-api, Hugh Dickins,
Johannes Weiner, Rik van Riel, KOSAKI Motohiro, Mel Gorman,
Jason Evans, zhangyanfei, Kirill A. Shutemov, Minchan Kim,
Russell King, linux-arm-kernel, Will Deacon, Steve Capper,
Catalin Marinas
In-Reply-To: <1413799924-17946-1-git-send-email-minchan@kernel.org>
MADV_FREE needs pmd_dirty and pmd_mkclean for detecting recent
overwrite of the contents since MADV_FREE syscall is called for
THP page.
This patch adds pmd_dirty and pmd_mkclean for THP page MADV_FREE
support.
Cc: Russell King <linux@arm.linux.org.uk>
Cc: linux-arm-kernel@lists.infradead.org
Acked-by: Will Deacon <will.deacon@arm.com>
Acked-by: Steve Capper <steve.capper@linaro.org>
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
arch/arm64/include/asm/pgtable.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
index 6d81471183ee..effc859084bc 100644
--- a/arch/arm64/include/asm/pgtable.h
+++ b/arch/arm64/include/asm/pgtable.h
@@ -275,10 +275,12 @@ void pmdp_splitting_flush(struct vm_area_struct *vma, unsigned long address,
#endif /* CONFIG_TRANSPARENT_HUGEPAGE */
#define pmd_young(pmd) pte_young(pmd_pte(pmd))
+#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
#define pmd_mksplitting(pmd) pte_pmd(pte_mkspecial(pmd_pte(pmd)))
#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
+#define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd)))
#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
#define pmd_mknotpresent(pmd) (__pmd(pmd_val(pmd) & ~PMD_TYPE_MASK))
--
2.0.0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v17 5/7] arm: add pmd_mkclean for THP
From: Minchan Kim @ 2014-10-20 10:12 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Michael Kerrisk, linux-api, Hugh Dickins,
Johannes Weiner, Rik van Riel, KOSAKI Motohiro, Mel Gorman,
Jason Evans, zhangyanfei, Kirill A. Shutemov, Minchan Kim,
Catalin Marinas, Russell King, linux-arm-kernel, Will Deacon,
Steve Capper
In-Reply-To: <1413799924-17946-1-git-send-email-minchan@kernel.org>
MADV_FREE needs pmd_dirty and pmd_mkclean for detecting recent
overwrite of the contents since MADV_FREE syscall is called for
THP page.
This patch adds pmd_mkclean for THP page MADV_FREE support.
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: linux-arm-kernel@lists.infradead.org
Acked-by: Will Deacon <will.deacon@arm.com>
Acked-by: Steve Capper <steve.capper@linaro.org>
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
arch/arm/include/asm/pgtable-3level.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index a31ecdad4b59..54dc91486c16 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -249,6 +249,7 @@ PMD_BIT_FUNC(mkold, &= ~PMD_SECT_AF);
PMD_BIT_FUNC(mksplitting, |= L_PMD_SECT_SPLITTING);
PMD_BIT_FUNC(mkwrite, &= ~L_PMD_SECT_RDONLY);
PMD_BIT_FUNC(mkdirty, |= L_PMD_SECT_DIRTY);
+PMD_BIT_FUNC(mkclean, &= ~L_PMD_SECT_DIRTY);
PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
#define pmd_mkhuge(pmd) (__pmd(pmd_val(pmd) & ~PMD_TABLE_BIT))
--
2.0.0
--
To unsubscribe, send a message with 'unsubscribe linux-mm' in
the body to majordomo@kvack.org. For more info on Linux MM,
see: http://www.linux-mm.org/ .
Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a>
^ permalink raw reply related
* [PATCH v17 4/7] powerpc: add pmd_[dirty|mkclean] for THP
From: Minchan Kim @ 2014-10-20 10:12 UTC (permalink / raw)
To: Andrew Morton
Cc: linux-kernel, linux-mm, Michael Kerrisk, linux-api, Hugh Dickins,
Johannes Weiner, Rik van Riel, KOSAKI Motohiro, Mel Gorman,
Jason Evans, zhangyanfei, Kirill A. Shutemov, Minchan Kim,
Benjamin Herrenschmidt, Paul Mackerras, linuxppc-dev,
Aneesh Kumar K.V
In-Reply-To: <1413799924-17946-1-git-send-email-minchan@kernel.org>
MADV_FREE needs pmd_dirty and pmd_mkclean for detecting recent
overwrite of the contents since MADV_FREE syscall is called for
THP page.
This patch adds pmd_dirty and pmd_mkclean for THP page MADV_FREE
support.
Cc: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: linuxppc-dev@lists.ozlabs.org
Reviewed-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Minchan Kim <minchan@kernel.org>
---
arch/powerpc/include/asm/pgtable-ppc64.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/include/asm/pgtable-ppc64.h b/arch/powerpc/include/asm/pgtable-ppc64.h
index 889c6fa9ee01..7c07e5975871 100644
--- a/arch/powerpc/include/asm/pgtable-ppc64.h
+++ b/arch/powerpc/include/asm/pgtable-ppc64.h
@@ -468,9 +468,11 @@ static inline pte_t *pmdp_ptep(pmd_t *pmd)
#define pmd_pfn(pmd) pte_pfn(pmd_pte(pmd))
#define pmd_young(pmd) pte_young(pmd_pte(pmd))
+#define pmd_dirty(pmd) pte_dirty(pmd_pte(pmd))
#define pmd_mkold(pmd) pte_pmd(pte_mkold(pmd_pte(pmd)))
#define pmd_wrprotect(pmd) pte_pmd(pte_wrprotect(pmd_pte(pmd)))
#define pmd_mkdirty(pmd) pte_pmd(pte_mkdirty(pmd_pte(pmd)))
+#define pmd_mkclean(pmd) pte_pmd(pte_mkclean(pmd_pte(pmd)))
#define pmd_mkyoung(pmd) pte_pmd(pte_mkyoung(pmd_pte(pmd)))
#define pmd_mkwrite(pmd) pte_pmd(pte_mkwrite(pmd_pte(pmd)))
--
2.0.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox