Quantcast
Channel: Serverphorums.com - Linux Kernel
Viewing all 24115 articles
Browse latest View live

[PATCH] fs: dax: do not build on ARC or SH (1 reply)

$
0
0
From: Arnd Bergmann <arnd@arndb.de>

The DAX implementation relies on the architecture to provide a working
copy_user_page() function, as reported by Michael Ellerman's kisskb
build bot:

fs/dax.c: error: implicit declaration of function 'copy_user_page' [-Werror=implicit-function-declaration]: => 266:2

We already have a list of architectures that are known to be incompatible,
but the list is missing ARC and SH at the moment. Further, blackfin and
c6x also lack support for this function, but are already excluded because
they do not support MMU-based kernels.

Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reported-by: Geert Uytterhoeven <geert@linux-m68k.org>
[Geert: s/SH/SUPERH/, as reported by Paul Bolle <pebolle@tiscali.nl>]
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
fs/Kconfig | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/fs/Kconfig b/fs/Kconfig
index 011f43365d7b1e53..53326a50a3ce3830 100644
--- a/fs/Kconfig
+++ b/fs/Kconfig
@@ -37,7 +37,7 @@ source "fs/f2fs/Kconfig"
config FS_DAX
bool "Direct Access (DAX) support"
depends on MMU
- depends on !(ARM || MIPS || SPARC)
+ depends on !(ARC || ARM || MIPS || SPARC || SUPERH)
help
Direct Access (DAX) can be used on memory-backed block devices.
If the block device supports DAX and the filesystem supports DAX,
--
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH v3] xen/blkfront: convert to blk-mq APIs (no replies)

$
0
0
Note: This patch is based on original work of Arianna's internship for
GNOME's Outreach Program for Women.

Only one hardware queue is used now, so there is no performance change.

The legacy non-mq code is deleted completely which is the same as other
drivers like virtio, mtip, and nvme.

Also dropped one unnecessary holding of info->io_lock when calling
blk_mq_stop_hw_queues().

Changes in v2:
- Reorganized blk_mq_queue_rq()
- Restored most io_locks in place

Change in v3:
- Rename blk_mq_queue_rq to blkif_queue_rq

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Signed-off-by: Bob Liu <bob.liu@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Acked-by: Jens Axboe <axboe@fb.com>
---
drivers/block/xen-blkfront.c | 146 +++++++++++++++++-------------------------
1 file changed, 60 insertions(+), 86 deletions(-)

diff --git a/drivers/block/xen-blkfront.c b/drivers/block/xen-blkfront.c
index 6d89ed3..5b45ee5 100644
--- a/drivers/block/xen-blkfront.c
+++ b/drivers/block/xen-blkfront.c
@@ -37,6 +37,7 @@

#include <linux/interrupt.h>
#include <linux/blkdev.h>
+#include <linux/blk-mq.h>
#include <linux/hdreg.h>
#include <linux/cdrom.h>
#include <linux/module.h>
@@ -148,6 +149,7 @@ struct blkfront_info
unsigned int feature_persistent:1;
unsigned int max_indirect_segments;
int is_ready;
+ struct blk_mq_tag_set tag_set;
};

static unsigned int nr_minors;
@@ -616,54 +618,41 @@ static inline bool blkif_request_flush_invalid(struct request *req,
!(info->feature_flush & REQ_FUA)));
}

-/*
- * do_blkif_request
- * read a block; request is in a request queue
- */
-static void do_blkif_request(struct request_queue *rq)
+static int blkif_queue_rq(struct blk_mq_hw_ctx *hctx,
+ const struct blk_mq_queue_data *qd)
{
- struct blkfront_info *info = NULL;
- struct request *req;
- int queued;
-
- pr_debug("Entered do_blkif_request\n");
-
- queued = 0;
+ struct blkfront_info *info = qd->rq->rq_disk->private_data;

- while ((req = blk_peek_request(rq)) != NULL) {
- info = req->rq_disk->private_data;
-
- if (RING_FULL(&info->ring))
- goto wait;
+ blk_mq_start_request(qd->rq);
+ spin_lock_irq(&info->io_lock);
+ if (RING_FULL(&info->ring))
+ goto out_busy;

- blk_start_request(req);
+ if (blkif_request_flush_invalid(qd->rq, info))
+ goto out_err;

- if (blkif_request_flush_invalid(req, info)) {
- __blk_end_request_all(req, -EOPNOTSUPP);
- continue;
- }
+ if (blkif_queue_request(qd->rq))
+ goto out_busy;

- pr_debug("do_blk_req %p: cmd %p, sec %lx, "
- "(%u/%u) [%s]\n",
- req, req->cmd, (unsigned long)blk_rq_pos(req),
- blk_rq_cur_sectors(req), blk_rq_sectors(req),
- rq_data_dir(req) ? "write" : "read");
-
- if (blkif_queue_request(req)) {
- blk_requeue_request(rq, req);
-wait:
- /* Avoid pointless unplugs. */
- blk_stop_queue(rq);
- break;
- }
+ flush_requests(info);
+ spin_unlock_irq(&info->io_lock);
+ return BLK_MQ_RQ_QUEUE_OK;

- queued++;
- }
+out_err:
+ spin_unlock_irq(&info->io_lock);
+ return BLK_MQ_RQ_QUEUE_ERROR;

- if (queued != 0)
- flush_requests(info);
+out_busy:
+ spin_unlock_irq(&info->io_lock);
+ blk_mq_stop_hw_queue(hctx);
+ return BLK_MQ_RQ_QUEUE_BUSY;
}

+static struct blk_mq_ops blkfront_mq_ops = {
+ .queue_rq = blkif_queue_rq,
+ .map_queue = blk_mq_map_queue,
+};
+
static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
unsigned int physical_sector_size,
unsigned int segments)
@@ -671,9 +660,22 @@ static int xlvbd_init_blk_queue(struct gendisk *gd, u16 sector_size,
struct request_queue *rq;
struct blkfront_info *info = gd->private_data;

- rq = blk_init_queue(do_blkif_request, &info->io_lock);
- if (rq == NULL)
+ memset(&info->tag_set, 0, sizeof(info->tag_set));
+ info->tag_set.ops = &blkfront_mq_ops;
+ info->tag_set.nr_hw_queues = 1;
+ info->tag_set.queue_depth = BLK_RING_SIZE(info);
+ info->tag_set.numa_node = NUMA_NO_NODE;
+ info->tag_set.flags = BLK_MQ_F_SHOULD_MERGE | BLK_MQ_F_SG_MERGE;
+ info->tag_set.cmd_size = 0;
+ info->tag_set.driver_data = info;
+
+ if (blk_mq_alloc_tag_set(&info->tag_set))
return -1;
+ rq = blk_mq_init_queue(&info->tag_set);
+ if (IS_ERR(rq)) {
+ blk_mq_free_tag_set(&info->tag_set);
+ return -1;
+ }

queue_flag_set_unlocked(QUEUE_FLAG_VIRT, rq);

@@ -901,19 +903,15 @@ static int xlvbd_alloc_gendisk(blkif_sector_t capacity,
static void xlvbd_release_gendisk(struct blkfront_info *info)
{
unsigned int minor, nr_minors;
- unsigned long flags;

if (info->rq == NULL)
return;

- spin_lock_irqsave(&info->io_lock, flags);
-
/* No more blkif_request(). */
- blk_stop_queue(info->rq);
+ blk_mq_stop_hw_queues(info->rq);

/* No more gnttab callback work. */
gnttab_cancel_free_callback(&info->callback);
- spin_unlock_irqrestore(&info->io_lock, flags);

/* Flush gnttab callback work. Must be done with no locks held. */
flush_work(&info->work);
@@ -925,20 +923,18 @@ static void xlvbd_release_gendisk(struct blkfront_info *info)
xlbd_release_minors(minor, nr_minors);

blk_cleanup_queue(info->rq);
+ blk_mq_free_tag_set(&info->tag_set);
info->rq = NULL;

put_disk(info->gd);
info->gd = NULL;
}

+/* Must be called with io_lock holded */
static void kick_pending_request_queues(struct blkfront_info *info)
{
- if (!RING_FULL(&info->ring)) {
- /* Re-enable calldowns. */
- blk_start_queue(info->rq);
- /* Kick things off immediately. */
- do_blkif_request(info->rq);
- }
+ if (!RING_FULL(&info->ring))
+ blk_mq_start_stopped_hw_queues(info->rq, true);
}

static void blkif_restart_queue(struct work_struct *work)
@@ -963,7 +959,7 @@ static void blkif_free(struct blkfront_info *info, int suspend)
BLKIF_STATE_SUSPENDED : BLKIF_STATE_DISCONNECTED;
/* No more blkif_request(). */
if (info->rq)
- blk_stop_queue(info->rq);
+ blk_mq_stop_hw_queues(info->rq);

/* Remove all persistent grants */
if (!list_empty(&info->grants)) {
@@ -1144,7 +1140,6 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
RING_IDX i, rp;
unsigned long flags;
struct blkfront_info *info = (struct blkfront_info *)dev_id;
- int error;

spin_lock_irqsave(&info->io_lock, flags);

@@ -1185,37 +1180,37 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
continue;
}

- error = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO;
+ req->errors = (bret->status == BLKIF_RSP_OKAY) ? 0 : -EIO;
switch (bret->operation) {
case BLKIF_OP_DISCARD:
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
struct request_queue *rq = info->rq;
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
info->gd->disk_name, op_name(bret->operation));
- error = -EOPNOTSUPP;
+ req->errors = -EOPNOTSUPP;
info->feature_discard = 0;
info->feature_secdiscard = 0;
queue_flag_clear(QUEUE_FLAG_DISCARD, rq);
queue_flag_clear(QUEUE_FLAG_SECDISCARD, rq);
}
- __blk_end_request_all(req, error);
+ blk_mq_complete_request(req);
break;
case BLKIF_OP_FLUSH_DISKCACHE:
case BLKIF_OP_WRITE_BARRIER:
if (unlikely(bret->status == BLKIF_RSP_EOPNOTSUPP)) {
printk(KERN_WARNING "blkfront: %s: %s op failed\n",
info->gd->disk_name, op_name(bret->operation));
- error = -EOPNOTSUPP;
+ req->errors = -EOPNOTSUPP;
}
if (unlikely(bret->status == BLKIF_RSP_ERROR &&
info->shadow[id].req.u.rw.nr_segments == 0)) {
printk(KERN_WARNING "blkfront: %s: empty %s op failed\n",
info->gd->disk_name, op_name(bret->operation));
- error = -EOPNOTSUPP;
+ req->errors = -EOPNOTSUPP;
}
- if (unlikely(error)) {
- if (error == -EOPNOTSUPP)
- error = 0;
+ if (unlikely(req->errors)) {
+ if (req->errors == -EOPNOTSUPP)
+ req->errors = 0;
info->feature_flush = 0;
xlvbd_flush(info);
}
@@ -1226,7 +1221,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
dev_dbg(&info->xbdev->dev, "Bad return from blkdev data "
"request: %x\n", bret->status);

- __blk_end_request_all(req, error);
+ blk_mq_complete_request(req);
break;
default:
BUG();
@@ -1555,28 +1550,6 @@ static int blkif_recover(struct blkfront_info *info)

kfree(copy);

- /*
- * Empty the queue, this is important because we might have
- * requests in the queue with more segments than what we
- * can handle now.
- */
- spin_lock_irq(&info->io_lock);
- while ((req = blk_fetch_request(info->rq)) != NULL) {
- if (req->cmd_flags &
- (REQ_FLUSH | REQ_FUA | REQ_DISCARD | REQ_SECURE)) {
- list_add(&req->queuelist, &requests);
- continue;
- }
- merge_bio.head = req->bio;
- merge_bio.tail = req->biotail;
- bio_list_merge(&bio_list, &merge_bio);
- req->bio = NULL;
- if (req->cmd_flags & (REQ_FLUSH | REQ_FUA))
- pr_alert("diskcache flush request found!\n");
- __blk_end_request_all(req, 0);
- }
- spin_unlock_irq(&info->io_lock);
-
xenbus_switch_state(info->xbdev, XenbusStateConnected);

spin_lock_irq(&info->io_lock);
@@ -1591,9 +1564,10 @@ static int blkif_recover(struct blkfront_info *info)
/* Requeue pending requests (flush or discard) */
list_del_init(&req->queuelist);
BUG_ON(req->nr_phys_segments > segs);
- blk_requeue_request(info->rq, req);
+ blk_mq_requeue_request(req);
}
spin_unlock_irq(&info->io_lock);
+ blk_mq_kick_requeue_list(info->rq);

while ((bio = bio_list_pop(&bio_list)) != NULL) {
/* Traverse the list of pending bios and re-queue them */
--
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[v5 00/19] Add VT-d Posted-Interrupts support (19 replies)

$
0
0
VT-d Posted-Interrupts is an enhancement to CPU side Posted-Interrupt.
With VT-d Posted-Interrupts enabled, external interrupts from
direct-assigned devices can be delivered to guests without VMM
intervention when guest is running in non-root mode.

You can find the VT-d Posted-Interrtups Spec. in the following URL:
http://www.intel.com/content/www/us/en/intelligent-systems/intel-technology/vt-directed-io-spec.html

This series was part of http://thread.gmane.org/gmane.linux.kernel.iommu/7708. To make things clear, send out IOMMU part here.

This patch-set is based on the lastest x86/apic branch of tip tree.

Divide the whole series which contain multiple components into three parts:
- Prerequisite changes to irq subsystem (already merged)
- IOMMU part (already merged)
- KVM and VFIO parts (this series)

v5:
- Based on Alex and Eric's irq bypass manager:
https://lkml.org/lkml/2015/7/10/663
- Reuse some common patch from Eric

Eric Auger (3):
KVM: create kvm_irqfd.h
KVM: eventfd: add irq bypass information in irqfd
KVM: eventfd: add irq bypass consumer management

Feng Wu (16):
KVM: Extend struct pi_desc for VT-d Posted-Interrupts
KVM: Add some helper functions for Posted-Interrupts
KVM: Define a new interface kvm_intr_is_single_vcpu()
KVM: Get Posted-Interrupts descriptor address from struct kvm_vcpu
KVM: Add interfaces to control PI outside vmx
KVM: Make struct kvm_irq_routing_table accessible
KVM: make kvm_set_msi_irq() public
vfio: Select IRQ_BYPASS_MANAGER for vfio PCI devices
vfio: Register/unregister irq_bypass_producer
KVM, x86: Select IRQ_BYPASS_MANAGER for KVM_INTEL
KVM: x86: Update IRTE for posted-interrupts
KVM: x86: Add arch specific routines for irqbypass manager
KVM: Add an arch specific hooks in 'struct kvm_kernel_irqfd'
KVM: Update Posted-Interrupts Descriptor when vCPU is preempted
KVM: Update Posted-Interrupts Descriptor when vCPU is blocked
KVM: Warn if 'SN' is set during posting interrupts by software

arch/x86/include/asm/kvm_host.h | 15 ++
arch/x86/kvm/Kconfig | 1 +
arch/x86/kvm/irq_comm.c | 28 +++-
arch/x86/kvm/vmx.c | 278 +++++++++++++++++++++++++++++++++++-
arch/x86/kvm/x86.c | 160 +++++++++++++++++++--
drivers/vfio/pci/Kconfig | 1 +
drivers/vfio/pci/vfio_pci_intrs.c | 19 +++
drivers/vfio/pci/vfio_pci_private.h | 2 +
include/linux/kvm_host.h | 23 +++
include/linux/kvm_irqfd.h | 74 ++++++++++
virt/kvm/eventfd.c | 115 ++++++---------
virt/kvm/irqchip.c | 11 --
virt/kvm/kvm_main.c | 3 +
13 files changed, 632 insertions(+), 98 deletions(-)
create mode 100644 include/linux/kvm_irqfd.h

--
2.1.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH 1/3] dt-bindings: thermal: Add binding document for Mediatek thermal controller (no replies)

$
0
0
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
.../bindings/thermal/mediatek-thermal.txt | 38 ++++++++++++++++++++++
1 file changed, 38 insertions(+)
create mode 100644 Documentation/devicetree/bindings/thermal/mediatek-thermal.txt

diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
new file mode 100644
index 0000000..d90e4dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
@@ -0,0 +1,38 @@
+* Mediatek Thermal
+
+This describes the device tree binding for the Mediatek thermal controller
+which measures the on-SoC temperatures. This device does not have its own ADC,
+instead it directly controls the AUXADC via AHB bus accesses. For this reason
+this device needs phandles to the AUXADC. Also it controls a mux in the
+apmixedsys register space via AHB bus accesses, so a phandle to the APMIXEDSYS
+is also needed.
+
+Required properties:
+- compatible: "mediatek,mt8173-thermal"
+- reg: Address range of the thermal controller
+- interrupts: IRQ for the thermal controller
+- clocks, clock-names: Clocks needed for the thermal controller. required
+ clocks are:
+ "therm": Main clock needed for register access
+ "auxadc": The AUXADC clock
+- resets, reset-names: Reference to the reset controller controlling the thermal
+ controller. Required reset-names:
+ "therm": The main reset line
+- auxadc: A phandle to the AUXADC which the thermal controller uses
+- apmixedsys: A phandle to the APMIXEDSYS controller.
+- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description
+
+Example:
+
+ thermal: thermal@1100b000 {
+ #thermal-sensor-cells = <1>;
+ compatible = "mediatek,mt8173-thermal";
+ reg = <0 0x1100b000 0 0x1000>;
+ interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>;
+ clock-names = "therm", "auxadc";
+ resets = <&pericfg MT8173_PERI_THERM_SW_RST>;
+ reset-names = "therm";
+ auxadc = <&auxadc>;
+ apmixedsys = <&apmixedsys>;
+ };
--
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH 3/3] ARM64: dts: mt8173: Add thermal/auxadc device nodes (no replies)

$
0
0
Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
index 27237a1..8cd114a 100644
--- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -151,6 +151,11 @@
(GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>;
};

+ auxadc: auxadc@11001000 {
+ compatible = "mediatek,mt8173-auxadc";
+ reg = <0 0x11001000 0 0x1000>;
+ };
+
uart0: serial@11002000 {
compatible = "mediatek,mt8173-uart",
"mediatek,mt6577-uart";
@@ -186,6 +191,19 @@
clocks = <&uart_clk>;
status = "disabled";
};
+
+ thermal: thermal@1100b000 {
+ #thermal-sensor-cells = <1>;
+ compatible = "mediatek,mt8173-thermal";
+ reg = <0 0x1100b000 0 0x1000>;
+ interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>;
+ clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>;
+ clock-names = "therm", "auxadc";
+ resets = <&pericfg MT8173_PERI_THERM_SW_RST>;
+ reset-names = "therm";
+ auxadc = <&auxadc>;
+ apmixedsys = <&apmixedsys>;
+ };
};
};

--
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH] thermal: Add Mediatek thermal support (1 reply)

$
0
0
This series adds support for the thermal sensors included in the
MT8173 SoC. Currently only basic temperature reading is supported
without any interrupt support.

The cpufreq driver for MT8173 is currently under review, so there's no
real cooling device available in mainline. Until this is available the
thermal driver can be tested with the following dts snippet. It creates
a fake gpio fan and a fake trip point which is so low that it can easily
be reached with a "cat /dev/zero > /dev/null" on the command line.

Please review and let me know what's missing to be included in mainline.

Sascha

fan: gpio_fan {
compatible = "gpio-fan";
gpios = <&pio 24 0>;
gpio-fan,speed-map = <0 0
4500 1>;
#cooling-cells = <2>;
};

thermal-zones {
cpu_thermal: cpu_thermal {
polling-delay-passive = <1000>; /* milliseconds */
polling-delay = <1000>; /* milliseconds */

thermal-sensors = <&thermal 0>;

trips {
cpu_passive: cpu_passive {
temperature = <47000>; /* millicelsius */
hysteresis = <2000>; /* millicelsius */
type = "passive";
};

cpu_crit {
temperature = <90000>; /* millicelsius */
hysteresis = <2000>; /* millicelsius */
type = "critical";
};
};

cooling-maps {
map0 {
trip = <&cpu_passive>;
cooling-device = <&fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>;
};
};
};
};

----------------------------------------------------------------
Sascha Hauer (3):
dt-bindings: thermal: Add binding document for Mediatek thermal controller
thermal: Add Mediatek thermal controller support
ARM64: dts: mt8173: Add thermal/auxadc device nodes

.../bindings/thermal/mediatek-thermal.txt | 38 ++
arch/arm64/boot/dts/mediatek/mt8173.dtsi | 18 +
drivers/thermal/Kconfig | 8 +
drivers/thermal/Makefile | 1 +
drivers/thermal/mtk_thermal.c | 602 +++++++++++++++++++++
5 files changed, 667 insertions(+)
create mode 100644 Documentation/devicetree/bindings/thermal/mediatek-thermal.txt
create mode 100644 drivers/thermal/mtk_thermal.c
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH] Staging: android: ion: Fix Style Issue (1 reply)

$
0
0
Modified style issue in ion.c. Missing empty line after a definition

Signed-off-by: Craig <craig.inches@xayto.net>
---
drivers/staging/android/ion/ion.c | 1 +
1 file changed, 1 insertion(+)

diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index 6f48112..e44f5e6 100644
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -1106,6 +1106,7 @@ struct dma_buf *ion_share_dma_buf(struct ion_client *client,
struct ion_buffer *buffer;
struct dma_buf *dmabuf;
bool valid_handle;
+
DEFINE_DMA_BUF_EXPORT_INFO(exp_info);

mutex_lock(&client->lock);
--
2.3.6

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[GIT PULL] please pull file-locking related changes for v4.2 (no replies)

$
0
0
The following changes since commit b9243b5a5d2da4eb0a54950f4e2d6272863b48be:

Merge branch 'parisc-4.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller/parisc-linux (2015-07-10 16:54:37 -0700)

are available in the git repository at:

git://git.samba.org/jlayton/linux.git tags/locks-v4.2-1

for you to fetch changes up to ee296d7c5709440f8abd36b5b65c6b3e388538d9:

locks: inline posix_lock_file_wait and flock_lock_file_wait (2015-07-13 06:29:11 -0400)

----------------------------------------------------------------
File locking related changes for v4.2 (pile #1)

I had thought that I was going to get away without a pull request this
cycle. There was a NFSv4 file locking problem that cropped up that I
tried to fix in the NFSv4 code alone, but that fix has turned out to be
problematic. These patches fix this in the correct way.

Note that this touches some NFSv4 code as well. Ordinarily I'd wait for
Trond to ACK this, but he's on holiday right now and the bug is rather
nasty. So I suggest we merge this and if he raises issues with it we
can sort it out when he gets back.

----------------------------------------------------------------
Jeff Layton (5):
Revert "nfs: take extra reference to fl->fl_file when running a LOCKU operation"
locks: have flock_lock_file take an inode pointer instead of a filp
locks: new helpers - flock_lock_inode_wait and posix_lock_inode_wait
nfs4: have do_vfs_lock take an inode pointer
locks: inline posix_lock_file_wait and flock_lock_file_wait

fs/locks.c | 38 ++++++++++++++++++--------------------
fs/nfs/nfs4proc.c | 18 ++++++++----------
include/linux/fs.h | 30 ++++++++++++++++++++----------
3 files changed, 46 insertions(+), 40 deletions(-)


--
Jeff Layton <jlayton@poochiereds.net>

[PATCH 4/5] mm, madvise: use vma_is_anonymous() to check for anon VMA (no replies)

$
0
0
!vma->vm_file is not reliable to detect anon VMA, because not all
drivers bother set it. Let's use vma_is_anonymous() instead.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Minchan Kim <minchan@kernel.org>
---
mm/madvise.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/madvise.c b/mm/madvise.c
index 70ce0d425d72..a4fae076f61d 100644
--- a/mm/madvise.c
+++ b/mm/madvise.c
@@ -393,7 +393,7 @@ static int madvise_free_single_vma(struct vm_area_struct *vma,
return -EINVAL;

/* MADV_FREE works for only anon vma at the moment */
- if (vma->vm_file)
+ if (!vma_is_anonymous(vma))
return -EINVAL;

start = max(vma->vm_start, start_addr);
--
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH 5/5] mm, memcontrol: use vma_is_anonymous() to check for anon VMA (no replies)

$
0
0
!vma->vm_file is not reliable to detect anon VMA, because not all
drivers bother set it. Let's use vma_is_anonymous() instead.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Michal Hocko <mhocko@suse.cz>
---
mm/memcontrol.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/mm/memcontrol.c b/mm/memcontrol.c
index acb93c554f6e..a624709f0dd7 100644
--- a/mm/memcontrol.c
+++ b/mm/memcontrol.c
@@ -4809,7 +4809,7 @@ static struct page *mc_handle_file_pte(struct vm_area_struct *vma,
struct address_space *mapping;
pgoff_t pgoff;

- if (!vma->vm_file) /* anonymous vma */
+ if (vma_is_anonymous(vma)) /* anonymous vma */
return NULL;
if (!(mc.flags & MOVE_FILE))
return NULL;
--
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH 2/5] x86, mpx: do not set ->vm_ops on mpx VMAs (1 reply)

$
0
0
MPX setups private anonymous mapping, but uses vma->vm_ops too.
This can confuse core VM, as it relies on vm->vm_ops to distinguish
file VMAs from anonymous.

As result we will get SIGBUS, because handle_pte_fault() thinks it's
file VMA without vm_ops->fault and it doesn't know how to handle the
situation properly.

Let's fix that by not setting ->vm_ops.

We don't really need ->vm_ops here: MPX VMA can be detected with VM_MPX
flag. And vma_merge() will not merge MPX VMA with non-MPX VMA, because
->vm_flags won't match.

The only thing left is name of VMA. I'm not sure if it's part of ABI, or
we can just drop it. The patch keep it by providing arch_vma_name() on x86.

Build tested only.

Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Andy Lutomirski <luto@amacapital.net>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
arch/x86/mm/mmap.c | 7 +++++++
arch/x86/mm/mpx.c | 20 +-------------------
2 files changed, 8 insertions(+), 19 deletions(-)

diff --git a/arch/x86/mm/mmap.c b/arch/x86/mm/mmap.c
index 9d518d693b4b..844b06d67df4 100644
--- a/arch/x86/mm/mmap.c
+++ b/arch/x86/mm/mmap.c
@@ -126,3 +126,10 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
mm->get_unmapped_area = arch_get_unmapped_area_topdown;
}
}
+
+const char *arch_vma_name(struct vm_area_struct *vma)
+{
+ if (vma->vm_flags & VM_MPX)
+ return "[mpx]";
+ return NULL;
+}
diff --git a/arch/x86/mm/mpx.c b/arch/x86/mm/mpx.c
index c439ec478216..4d1c11c07fe1 100644
--- a/arch/x86/mm/mpx.c
+++ b/arch/x86/mm/mpx.c
@@ -18,26 +18,9 @@
#include <asm/processor.h>
#include <asm/fpu-internal.h>

-static const char *mpx_mapping_name(struct vm_area_struct *vma)
-{
- return "[mpx]";
-}
-
-static struct vm_operations_struct mpx_vma_ops = {
- .name = mpx_mapping_name,
-};
-
-static int is_mpx_vma(struct vm_area_struct *vma)
-{
- return (vma->vm_ops == &mpx_vma_ops);
-}
-
/*
* This is really a simplified "vm_mmap". it only handles MPX
* bounds tables (the bounds directory is user-allocated).
- *
- * Later on, we use the vma->vm_ops to uniquely identify these
- * VMAs.
*/
static unsigned long mpx_mmap(unsigned long len)
{
@@ -83,7 +66,6 @@ static unsigned long mpx_mmap(unsigned long len)
ret = -ENOMEM;
goto out;
}
- vma->vm_ops = &mpx_vma_ops;

if (vm_flags & VM_LOCKED) {
up_write(&mm->mmap_sem);
@@ -661,7 +643,7 @@ static int zap_bt_entries(struct mm_struct *mm,
* so stop immediately and return an error. This
* probably results in a SIGSEGV.
*/
- if (!is_mpx_vma(vma))
+ if (!(vma->vm_flags & VM_MPX))
return -EINVAL;

len = min(vma->vm_end, end) - addr;
--
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH 0/5] Make vma_is_anonymous() reliable (2 replies)

$
0
0
We rely on ->vm_ops == NULL to detect anonymous VMA but this check is not
always reliable:

- MPX sets ->vm_ops on anonymous VMA;

- many drivers don't set ->vm_ops. See for instance hpet_mmap().

This patchset makes vma_is_anonymous() more reliable and makes few
cleanups around the code.

Kirill A. Shutemov (5):
mm: mark most vm_operations_struct const
x86, mpx: do not set ->vm_ops on mpx VMAs
mm: make sure all file VMAs have ->vm_ops set
mm, madvise: use vma_is_anonymous() to check for anon VMA
mm, memcontrol: use vma_is_anonymous() to check for anon VMA

arch/x86/kernel/vsyscall_64.c | 2 +-
arch/x86/mm/mmap.c | 7 +++++++
arch/x86/mm/mpx.c | 20 +-------------------
drivers/android/binder.c | 2 +-
drivers/gpu/drm/vgem/vgem_drv.c | 2 +-
drivers/hsi/clients/cmt_speech.c | 2 +-
drivers/infiniband/hw/qib/qib_file_ops.c | 2 +-
drivers/infiniband/hw/qib/qib_mmap.c | 2 +-
drivers/media/platform/omap/omap_vout.c | 2 +-
drivers/misc/genwqe/card_dev.c | 2 +-
drivers/staging/android/ion/ion.c | 2 +-
drivers/staging/comedi/comedi_fops.c | 2 +-
drivers/video/fbdev/omap2/omapfb/omapfb-main.c | 2 +-
drivers/xen/gntalloc.c | 2 +-
drivers/xen/gntdev.c | 2 +-
drivers/xen/privcmd.c | 4 ++--
fs/ceph/addr.c | 2 +-
fs/cifs/file.c | 2 +-
mm/madvise.c | 2 +-
mm/memcontrol.c | 2 +-
mm/mmap.c | 8 ++++++++
security/selinux/selinuxfs.c | 2 +-
22 files changed, 36 insertions(+), 39 deletions(-)

--
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH v9 4/4] arm/dts/ls1021a: Add a TFT LCD panel dts node (no replies)

$
0
0
Add a TFT LCD panel. the TFT LCD panel is WQVGA "480x272",
and the bpp is 24.

Signed-off-by: Alison Wang <b18965@freescale.com>
Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com>
Signed-off-by: Jianwei Wang <b52261@freescale.com>
Reviewed-by: Alison Wang <alison.wang@freescale.com>
---
arch/arm/boot/dts/ls1021a-twr.dts | 11 +++++++++++
1 file changed, 11 insertions(+)

diff --git a/arch/arm/boot/dts/ls1021a-twr.dts b/arch/arm/boot/dts/ls1021a-twr.dts
index a2c591e..f6ad7ba 100644
--- a/arch/arm/boot/dts/ls1021a-twr.dts
+++ b/arch/arm/boot/dts/ls1021a-twr.dts
@@ -56,6 +56,17 @@
enet0_sgmii_phy = &sgmii_phy2;
enet1_sgmii_phy = &sgmii_phy0;
};
+
+ panel: panel {
+ compatible = "nec,nl4827hc19_05b";
+ };
+
+};
+
+&dcu {
+ panel = <&panel>;
+ status = "okay";
+
};

&dspi1 {
--
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH v9 3/4] arm/dts/ls1021a: Add DCU dts node (no replies)

$
0
0
Add DCU node, DCU is a display controller of Freescale
named 2D-ACE.

Signed-off-by: Alison Wang <b18965@freescale.com>
Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com>
Signed-off-by: Jianwei Wang <b52261@freescale.com>
Reviewed-by: Alison Wang <alison.wang@freescale.com>
---
.../devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt | 20 ++++++++++++++++++++
MAINTAINERS | 1 +
arch/arm/boot/dts/ls1021a.dtsi | 10 ++++++++++
3 files changed, 31 insertions(+)
create mode 100644 Documentation/devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt

diff --git a/Documentation/devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt b/Documentation/devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt
new file mode 100644
index 0000000..eb61ea5
--- /dev/null
+++ b/Documentation/devicetree/bindings/drm/fsl-dcu/fsl,dcu.txt
@@ -0,0 +1,20 @@
+Device Tree bindings for Freescale DCU DRM Driver
+
+Required properties:
+- compatible: Should be one of
+ * "fsl,ls1021a-dcu".
+ * "fsl,vf610-dcu".
+- reg: Address and length of the register set for dcu.
+- clocks: From common clock binding: handle to dcu clock.
+- clock-names: From common clock binding: Shall be "dcu".
+- panel: The phandle to panel node.
+
+Examples:
+dcu: dcu@2ce0000 {
+ compatible = "fsl,ls1021a-dcu";
+ reg = <0x0 0x2ce0000 0x0 0x10000>;
+ clocks = <&platform_clk 0>;
+ clock-names = "dcu";
+ big-endian;
+ panel = <&panel>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index e191ded..fffb8c9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3410,6 +3410,7 @@ M: Alison Wang <alison.wang@freescale.com>
L: dri-devel@lists.freedesktop.org
S: Supported
F: drivers/gpu/drm/fsl-dcu/
+F: Documentation/devicetree/bindings/drm/fsl-dcu/
F: Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt

DRM DRIVERS FOR NVIDIA TEGRA
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index c70bb27..6d6e3e2 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -383,6 +383,16 @@
<&platform_clk 1>;
};

+ dcu: dcu@2ce0000 {
+ compatible = "fsl,ls1021a-dcu";
+ reg = <0x0 0x2ce0000 0x0 0x10000>;
+ interrupts = <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 0>;
+ clock-names = "dcu";
+ big-endian;
+ status = "disabled";
+ };
+
mdio0: mdio@2d24000 {
compatible = "gianfar";
device_type = "mdio";
--
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH v9 1/4] drm/layerscape: Add Freescale DCU DRM driver (1 reply)

$
0
0
This patch add support for Two Dimensional Animation and Compositing
Engine (2D-ACE) on the Freescale SoCs.

2D-ACE is a Freescale display controller. 2D-ACE describes
the functionality of the module extremely well its name is a value
that cannot be used as a token in programming languages.
Instead the valid token "DCU" is used to tag the register names and
function names.

The Display Controller Unit (DCU) module is a system master that
fetches graphics stored in internal or external memory and displays
them on a TFT LCD panel. A wide range of panel sizes is supported
and the timing of the interface signals is highly configurable.
Graphics are read directly from memory and then blended in real-time,
which allows for dynamic content creation with minimal CPU
intervention.

The features:
(1) Full RGB888 output to TFT LCD panel.
(2) For the current LCD panel, WQVGA "480x272" is supported.
(3) Blending of each pixel using up to 4 source layers
dependent on size of panel.
(4) Each graphic layer can be placed with one pixel resolution
in either axis.
(5) Each graphic layer support RGB565 and RGB888 direct colors
without alpha
channel and BGRA8888 BGRA4444 ARGB1555 direct colors with an
alpha channel and YUV422 format.
(6) Each graphic layer support alpha blending with 8-bit
resolution.

This is a simplified version, only one primary plane, one
framebuffer, one crtc, one connector and one encoder for TFT
LCD panel.

Signed-off-by: Alison Wang <b18965@freescale.com>
Signed-off-by: Xiubo Li <lixiubo@cmss.chinamobile.com>
Signed-off-by: Jianwei Wang <b52261@freescale.com>
Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Alison Wang <alison.wang@freescale.com>
---


Changed in V9

-put node after calling of_drm_find_panel
-split clk_prepare_enable() to clk_prepare() and clk_enable(),
just call clk_prepare once, and check return value
-check regmap_write/regmap_read return return value
-remove useless ".owner = THIS_MODULE,"
All advanced by Mark Yao

Changed in V8

- Remove useless code
#define DRIVER_NAME "fsl-dcu-drm"
MODULE_ALIAS("platform:fsl-dcu-drm");
Adviced by Paul Bolle

Changed in V7

- Remove redundant functions and replace deprecated hooker
Adviced by Daniel Vetter
- Replace drm_platform_init with drm_dev_alloc/register
Adviced by Daniel Vetter

Changed in V6

- Add NEC nl4827hc19_05b panel to panel-simple.c
Adviced by Mark Yao
- Add DRIVER_ATOMIC for driver_features
Adviced by Mark Yao
- check fsl_dev if it's NULL at PM suspend/resume
Adviced by Mark Yao

Changed in V5

- Update commit message
- Add layer registers initialization
- Remove unused functions
- Rename driver folder
Adviced by Stefan Agner
- Move pixel clock control functions to fsl_dcu_drm_drv.c
- remove redundant enable the clock implicitly using regmap
- Add maintainer message

Changed in V4:

-This version doesn't have functionality changed
Just a minor adjustment.

Changed in V3:

- Test driver on Vybrid board and add compatible string
- Remove unused functions
- set default crtc for encoder
- replace legacy functions with atomic help functions
Adviced by Daniel Vetter
- Set the unique name of the DRM device
- Implement irq handle function for vblank interrupt

Changed in v2:
- Add atomic support
Adviced by Daniel Vetter
- Modify bindings file
- Rename node for compatibility
- Move platform related code out for compatibility
Adviced by Stefan Agner


MAINTAINERS | 9 +
drivers/gpu/drm/Kconfig | 2 +
drivers/gpu/drm/Makefile | 1 +
drivers/gpu/drm/fsl-dcu/Kconfig | 18 +
drivers/gpu/drm/fsl-dcu/Makefile | 7 +
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c | 187 ++++++++++
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h | 31 ++
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c | 212 +++++++++++
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h | 22 ++
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c | 453 ++++++++++++++++++++++++
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h | 222 ++++++++++++
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c | 26 ++
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c | 42 +++
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h | 17 +
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c | 227 ++++++++++++
drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h | 23 ++
16 files changed, 1499 insertions(+)
create mode 100644 drivers/gpu/drm/fsl-dcu/Kconfig
create mode 100644 drivers/gpu/drm/fsl-dcu/Makefile
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
create mode 100644 drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h

diff --git a/MAINTAINERS b/MAINTAINERS
index 6761318..fffb8c9 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3404,6 +3404,15 @@ S: Maintained
F: drivers/gpu/drm/imx/
F: Documentation/devicetree/bindings/drm/imx/

+DRM DRIVERS FOR FREESCALE DCU
+M: Jianwei Wang <jianwei.wang@freescale.com>
+M: Alison Wang <alison.wang@freescale.com>
+L: dri-devel@lists.freedesktop.org
+S: Supported
+F: drivers/gpu/drm/fsl-dcu/
+F: Documentation/devicetree/bindings/drm/fsl-dcu/
+F: Documentation/devicetree/bindings/panel/nec,nl4827hc19_05b.txt
+
DRM DRIVERS FOR NVIDIA TEGRA
M: Thierry Reding <thierry.reding@gmail.com>
M: Terje Bergström <tbergstrom@nvidia.com>
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index c46ca31..9cfd14e 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -231,6 +231,8 @@ source "drivers/gpu/drm/virtio/Kconfig"

source "drivers/gpu/drm/msm/Kconfig"

+source "drivers/gpu/drm/fsl-dcu/Kconfig"
+
source "drivers/gpu/drm/tegra/Kconfig"

source "drivers/gpu/drm/panel/Kconfig"
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 5713d05..11cb81e 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -70,3 +70,4 @@ obj-$(CONFIG_DRM_IMX) += imx/
obj-y += i2c/
obj-y += panel/
obj-y += bridge/
+obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu/
diff --git a/drivers/gpu/drm/fsl-dcu/Kconfig b/drivers/gpu/drm/fsl-dcu/Kconfig
new file mode 100644
index 0000000..bfd484b
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/Kconfig
@@ -0,0 +1,18 @@
+config DRM_FSL_DCU
+ tristate "DRM Support for Freescale DCU"
+ depends on DRM && OF && ARM
+ select DRM_KMS_HELPER
+ select DRM_KMS_CMA_HELPER
+ select VIDEOMODE_HELPERS
+ select BACKLIGHT_CLASS_DEVICE
+ select BACKLIGHT_LCD_SUPPORT
+ select REGMAP_MMIO
+ select DRM_KMS_FB_HELPER
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select DRM_PANEL
+ help
+ Choose this option if you have an Freescale DCU chipset.
+ If M is selected the module will be called fsl-dcu-drm.
diff --git a/drivers/gpu/drm/fsl-dcu/Makefile b/drivers/gpu/drm/fsl-dcu/Makefile
new file mode 100644
index 0000000..336b4a6
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/Makefile
@@ -0,0 +1,7 @@
+fsl-dcu-drm-y := fsl_dcu_drm_drv.o \
+ fsl_dcu_drm_kms.o \
+ fsl_dcu_drm_connector.o \
+ fsl_dcu_drm_plane.o \
+ fsl_dcu_drm_crtc.o \
+ fsl_dcu_drm_fbdev.o
+obj-$(CONFIG_DRM_FSL_DCU) += fsl-dcu-drm.o
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c
new file mode 100644
index 0000000..41dd1d0
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.c
@@ -0,0 +1,187 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * 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/backlight.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_panel.h>
+
+#include "fsl_dcu_drm_drv.h"
+#include "fsl_dcu_drm_connector.h"
+
+static void fsl_dcu_drm_encoder_disable(struct drm_encoder *encoder)
+{
+}
+
+static int
+fsl_dcu_drm_encoder_atomic_check(struct drm_encoder *encoder,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
+{
+ return 0;
+}
+
+static void fsl_dcu_drm_encoder_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+}
+
+static void fsl_dcu_drm_encoder_enable(struct drm_encoder *encoder)
+{
+}
+
+static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
+ .enable = fsl_dcu_drm_encoder_enable,
+ .disable = fsl_dcu_drm_encoder_disable,
+ .atomic_check = fsl_dcu_drm_encoder_atomic_check,
+};
+
+static const struct drm_encoder_funcs encoder_funcs = {
+ .destroy = fsl_dcu_drm_encoder_destroy,
+};
+
+int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev,
+ struct drm_crtc *crtc)
+{
+ struct drm_encoder *encoder = &fsl_dev->encoder;
+ int ret;
+
+ encoder->possible_crtcs = 1;
+ ret = drm_encoder_init(fsl_dev->ddev, encoder, &encoder_funcs,
+ DRM_MODE_ENCODER_LVDS);
+ if (ret < 0)
+ return ret;
+
+ drm_encoder_helper_add(encoder, &encoder_helper_funcs);
+ encoder->crtc = crtc;
+
+ return 0;
+}
+
+#define to_fsl_dcu_connector(connector) \
+ container_of(connector, struct fsl_dcu_drm_connector, connector)
+
+static int fsl_dcu_drm_connector_get_modes(struct drm_connector *connector)
+{
+ struct fsl_dcu_drm_connector *fsl_connector;
+ int num_modes = 0;
+
+ fsl_connector = to_fsl_dcu_connector(connector);
+ if (fsl_connector->panel && fsl_connector->panel->funcs &&
+ fsl_connector->panel->funcs->get_modes)
+ num_modes = fsl_connector->panel->funcs->get_modes
+ (fsl_connector->panel);
+
+ return num_modes;
+}
+
+static int fsl_dcu_drm_connector_mode_valid(struct drm_connector *connector,
+ struct drm_display_mode *mode)
+{
+ return MODE_OK;
+}
+
+static struct drm_encoder *
+fsl_dcu_drm_connector_best_encoder(struct drm_connector *connector)
+{
+ struct fsl_dcu_drm_connector *fsl_con = to_fsl_dcu_connector(connector);
+
+ return fsl_con->encoder;
+}
+
+static void fsl_dcu_drm_connector_destroy(struct drm_connector *connector)
+{
+ drm_connector_unregister(connector);
+ drm_connector_cleanup(connector);
+}
+
+static enum drm_connector_status
+fsl_dcu_drm_connector_detect(struct drm_connector *connector, bool force)
+{
+ return connector_status_connected;
+}
+
+static const struct drm_connector_funcs fsl_dcu_drm_connector_funcs = {
+ .dpms = drm_atomic_helper_connector_dpms,
+ .reset = drm_atomic_helper_connector_reset,
+ .detect = fsl_dcu_drm_connector_detect,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+ .destroy = fsl_dcu_drm_connector_destroy,
+ .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static const struct drm_connector_helper_funcs connector_helper_funcs = {
+ .get_modes = fsl_dcu_drm_connector_get_modes,
+ .mode_valid = fsl_dcu_drm_connector_mode_valid,
+ .best_encoder = fsl_dcu_drm_connector_best_encoder,
+};
+
+int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
+ struct drm_encoder *encoder)
+{
+ struct drm_connector *connector = &fsl_dev->connector.connector;
+ struct device_node *panel_node;
+ int ret;
+
+ fsl_dev->connector.encoder = encoder;
+
+ connector->display_info.width_mm = 0;
+ connector->display_info.height_mm = 0;
+
+ ret = drm_connector_init(fsl_dev->ddev, connector,
+ &fsl_dcu_drm_connector_funcs,
+ DRM_MODE_CONNECTOR_LVDS);
+ if (ret < 0)
+ return ret;
+
+ connector->dpms = DRM_MODE_DPMS_OFF;
+ drm_connector_helper_add(connector, &connector_helper_funcs);
+ ret = drm_connector_register(connector);
+ if (ret < 0)
+ goto err_cleanup;
+
+ ret = drm_mode_connector_attach_encoder(connector, encoder);
+ if (ret < 0)
+ goto err_sysfs;
+
+ connector->encoder = encoder;
+
+ drm_object_property_set_value
+ (&connector->base, fsl_dev->ddev->mode_config.dpms_property,
+ DRM_MODE_DPMS_OFF);
+
+ panel_node = of_parse_phandle(fsl_dev->np, "panel", 0);
+ if (panel_node) {
+ fsl_dev->connector.panel = of_drm_find_panel(panel_node);
+ if (!fsl_dev->connector.panel) {
+ of_node_put(panel_node);
+ ret = -EPROBE_DEFER;
+ goto err_sysfs;
+ }
+ }
+ of_node_put(panel_node);
+
+ ret = drm_panel_attach(fsl_dev->connector.panel, connector);
+ if (ret) {
+ dev_err(fsl_dev->dev, "failed to attach panel\n");
+ goto err_sysfs;
+ }
+
+ return 0;
+
+err_sysfs:
+ drm_connector_unregister(connector);
+err_cleanup:
+ drm_connector_cleanup(connector);
+ return ret;
+}
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h
new file mode 100644
index 0000000..1c3dbb2
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_connector.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __FSL_DCU_DRM_CONNECTOR_H__
+#define __FSL_DCU_DRM_CONNECTOR_H__
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include "fsl_dcu_drm_crtc.h"
+
+struct fsl_dcu_drm_device;
+struct fsl_dcu_drm_connector {
+ struct drm_connector connector;
+ struct drm_encoder *encoder;
+ struct drm_panel *panel;
+};
+
+int fsl_dcu_drm_encoder_create(struct fsl_dcu_drm_device *fsl_dev,
+ struct drm_crtc *crtc);
+int fsl_dcu_drm_connector_create(struct fsl_dcu_drm_device *fsl_dev,
+ struct drm_encoder *encoder);
+
+#endif /* __FSL_DCU_DRM_CONNECTOR_H__ */
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
new file mode 100644
index 0000000..df69629
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.c
@@ -0,0 +1,212 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * 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/regmap.h>
+#include <linux/clk.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_atomic.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_crtc.h>
+
+#include "fsl_dcu_drm_crtc.h"
+#include "fsl_dcu_drm_drv.h"
+#include "fsl_dcu_drm_plane.h"
+
+#define to_fsl_dcu_crtc(c) container_of(c, struct fsl_dcu_drm_crtc, crtc)
+
+static void fsl_dcu_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+ struct drm_display_mode *mode = &crtc->state->mode;
+ uint32_t hbp, hfp, hsw, vbp, vfp, vsw, div, index;
+ int err;
+
+ DBG(": set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
+ mode->base.id, mode->name,
+ mode->vrefresh, mode->clock,
+ mode->hdisplay, mode->hsync_start,
+ mode->hsync_end, mode->htotal,
+ mode->vdisplay, mode->vsync_start,
+ mode->vsync_end, mode->vtotal,
+ mode->type, mode->flags);
+
+ index = drm_crtc_index(crtc);
+ div = (uint32_t)clk_get_rate(fsl_dev->clk) / mode->clock / 1000;
+
+ /* Configure timings: */
+ hbp = mode->htotal - mode->hsync_end;
+ hfp = mode->hsync_start - mode->hdisplay;
+ hsw = mode->hsync_end - mode->hsync_start;
+ vbp = mode->vtotal - mode->vsync_end;
+ vfp = mode->vsync_start - mode->vdisplay;
+ vsw = mode->vsync_end - mode->vsync_start;
+
+ err = regmap_write(fsl_dev->regmap, DCU_HSYN_PARA,
+ DCU_HSYN_PARA_BP(hbp) |
+ DCU_HSYN_PARA_PW(hsw) |
+ DCU_HSYN_PARA_FP(hfp));
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_VSYN_PARA,
+ DCU_VSYN_PARA_BP(vbp) |
+ DCU_VSYN_PARA_PW(vsw) |
+ DCU_VSYN_PARA_FP(vfp));
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_DISP_SIZE,
+ DCU_DISP_SIZE_DELTA_Y(mode->vdisplay) |
+ DCU_DISP_SIZE_DELTA_X(mode->hdisplay));
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_DIV_RATIO, div);
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
+ DCU_UPDATE_MODE_READREG);
+ if (err)
+ goto set_failed;
+ return;
+set_failed:
+ dev_err(dev->dev, "set DCU register failed\n");
+}
+
+static bool fsl_dcu_drm_crtc_mode_fixup(struct drm_crtc *crtc,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode)
+{
+ return true;
+}
+
+static void fsl_dcu_drm_crtc_enable(struct drm_crtc *crtc)
+{
+}
+
+static int fsl_dcu_drm_crtc_atomic_check(struct drm_crtc *crtc,
+ struct drm_crtc_state *state)
+{
+ return 0;
+}
+
+static void fsl_dcu_drm_crtc_atomic_begin(struct drm_crtc *crtc)
+{
+}
+
+static void fsl_dcu_drm_crtc_atomic_flush(struct drm_crtc *crtc)
+{
+}
+
+static void fsl_dcu_drm_disable_crtc(struct drm_crtc *crtc)
+{
+}
+
+static const struct drm_crtc_funcs fsl_dcu_drm_crtc_funcs = {
+ .page_flip = drm_atomic_helper_page_flip,
+ .set_config = drm_atomic_helper_set_config,
+ .destroy = drm_crtc_cleanup,
+ .reset = drm_atomic_helper_crtc_reset,
+ .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
+};
+
+static const struct drm_crtc_helper_funcs fsl_dcu_drm_crtc_helper_funcs = {
+ .enable = fsl_dcu_drm_crtc_enable,
+ .disable = fsl_dcu_drm_disable_crtc,
+ .mode_fixup = fsl_dcu_drm_crtc_mode_fixup,
+ .mode_set_nofb = fsl_dcu_drm_crtc_mode_set_nofb,
+ .atomic_check = fsl_dcu_drm_crtc_atomic_check,
+ .atomic_begin = fsl_dcu_drm_crtc_atomic_begin,
+ .atomic_flush = fsl_dcu_drm_crtc_atomic_flush,
+};
+
+int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev)
+{
+ struct drm_plane *primary;
+ struct drm_crtc *crtc = &fsl_dev->crtc;
+ int i, ret;
+
+ primary = fsl_dcu_drm_primary_create_plane(fsl_dev->ddev);
+ ret = drm_crtc_init_with_planes(fsl_dev->ddev, crtc, primary, NULL,
+ &fsl_dcu_drm_crtc_funcs);
+ if (ret < 0)
+ return ret;
+
+ drm_crtc_helper_add(crtc, &fsl_dcu_drm_crtc_helper_funcs);
+
+ for (i = 0; i < DCU_TOTAL_LAYER_NUM; i++) {
+ ret = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_1(i), 0);
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_2(i), 0);
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_3(i), 0);
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_4(i), 0);
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_5(i), 0);
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_6(i), 0);
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_7(i), 0);
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_8(i), 0);
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_9(i), 0);
+ if (ret)
+ goto init_failed;
+ if (of_device_is_compatible(fsl_dev->np, "fsl,ls1021a-dcu")) {
+ ret = regmap_write(fsl_dev->regmap,
+ DCU_CTRLDESCLN_10(i), 0);
+ if (ret)
+ goto init_failed;
+ }
+ }
+ ret = regmap_write(fsl_dev->regmap, DCU_SYN_POL,
+ DCU_SYN_POL_INV_VS_LOW | DCU_SYN_POL_INV_HS_LOW);
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_BGND, DCU_BGND_R(0) |
+ DCU_BGND_G(0) | DCU_BGND_B(0));
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_DCU_MODE,
+ DCU_MODE_BLEND_ITER(1) | DCU_MODE_RASTER_EN);
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_THRESHOLD,
+ DCU_THRESHOLD_LS_BF_VS(BF_VS_VAL) |
+ DCU_THRESHOLD_OUT_BUF_HIGH(BUF_MAX_VAL) |
+ DCU_THRESHOLD_OUT_BUF_LOW(BUF_MIN_VAL));
+ if (ret)
+ goto init_failed;
+ ret = regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
+ DCU_MODE_DCU_MODE_MASK,
+ DCU_MODE_DCU_MODE(DCU_MODE_OFF));
+ if (ret)
+ goto init_failed;
+ ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
+ DCU_UPDATE_MODE_READREG);
+ if (ret)
+ goto init_failed;
+
+ return 0;
+init_failed:
+ dev_err(fsl_dev->dev, "init DCU register failed\n");
+ return ret;
+}
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h
new file mode 100644
index 0000000..193785f
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_crtc.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __FSL_DCU_DRM_CRTC_H__
+#define __FSL_DCU_DRM_CRTC_H__
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+
+struct fsl_dcu_drm_device;
+
+int fsl_dcu_drm_crtc_create(struct fsl_dcu_drm_device *fsl_dev);
+
+#endif /* __FSL_DCU_DRM_CRTC_H__ */
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
new file mode 100644
index 0000000..6c5bb97
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -0,0 +1,453 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * 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/clk.h>
+#include <linux/io.h>
+#include <linux/mm.h>
+#include <linux/module.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_runtime.h>
+#include <linux/regmap.h>
+#include <linux/mfd/syscon.h>
+
+#include <drm/drmP.h>
+
+#include "fsl_dcu_drm_drv.h"
+#include "fsl_dcu_drm_crtc.h"
+#include "fsl_dcu_drm_kms.h"
+
+static int fsl_dcu_unload(struct drm_device *dev)
+{
+ drm_mode_config_cleanup(dev);
+ drm_vblank_cleanup(dev);
+ drm_irq_uninstall(dev);
+
+ dev->dev_private = NULL;
+
+ return 0;
+}
+
+static struct regmap_config fsl_dcu_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+};
+
+static int fsl_dcu_bypass_tcon(struct fsl_dcu_drm_device *fsl_dev,
+ struct device_node *np)
+{
+ struct device_node *tcon_np;
+ struct platform_device *pdev;
+ struct clk *tcon_clk;
+ struct resource *res;
+ void __iomem *base;
+ int ret;
+
+ tcon_np = of_parse_phandle(np, "tcon-controller", 0);
+ if (!tcon_np)
+ return -EINVAL;
+
+ pdev = of_find_device_by_node(tcon_np);
+ if (!pdev)
+ return -EINVAL;
+
+ tcon_clk = devm_clk_get(&pdev->dev, "tcon");
+ if (IS_ERR(tcon_clk))
+ return PTR_ERR(tcon_clk);
+ ret = clk_prepare(tcon_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to prepare tcon clk\n");
+ return ret;
+ }
+ ret = clk_enable(tcon_clk);
+ if (ret < 0) {
+ dev_err(&pdev->dev, "failed to enable tcon clk\n");
+ clk_unprepare(tcon_clk);
+ return ret;
+ }
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENODEV;
+
+ base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(base))
+ return PTR_ERR(base);
+
+ fsl_dev->tcon_regmap = devm_regmap_init_mmio(&pdev->dev,
+ base, &fsl_dcu_regmap_config);
+ if (IS_ERR(fsl_dev->tcon_regmap)) {
+ dev_err(&pdev->dev, "regmap init failed\n");
+ return PTR_ERR(fsl_dev->tcon_regmap);
+ }
+
+ ret = regmap_write(fsl_dev->tcon_regmap,
+ TCON_CTRL1, TCON_BYPASS_ENABLE);
+ if (ret) {
+ dev_err(&pdev->dev, "set TCON_CTRL1 failed\n");
+ return ret;
+ }
+ return 0;
+}
+
+static void dcu_pixclk_enable(void)
+{
+ struct regmap *scfg_regmap;
+
+ scfg_regmap = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg");
+ if (IS_ERR(scfg_regmap)) {
+ pr_err("No syscfg phandle specified\n");
+ return;
+ }
+
+ regmap_write(scfg_regmap, SCFG_PIXCLKCR, PXCK_ENABLE);
+}
+
+static int fsl_dcu_drm_irq_init(struct drm_device *dev)
+{
+ struct platform_device *pdev = to_platform_device(dev->dev);
+ struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+ unsigned int int_mask;
+ int ret;
+
+ ret = drm_irq_install(dev, platform_get_irq(pdev, 0));
+ if (ret < 0)
+ dev_err(&pdev->dev, "failed to install IRQ handler\n");
+
+ dev->irq_enabled = true;
+ dev->vblank_disable_allowed = true;
+
+ ret = regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0);
+ if (ret)
+ dev_err(&pdev->dev, "set DCU_INT_STATUS failed\n");
+ ret = regmap_read(fsl_dev->regmap, DCU_INT_MASK, &int_mask);
+ if (ret)
+ dev_err(&pdev->dev, "read DCU_INT_MASK failed\n");
+ ret = regmap_write(fsl_dev->regmap, DCU_INT_MASK, int_mask &
+ ~DCU_INT_MASK_VBLANK);
+ if (ret)
+ dev_err(&pdev->dev, "set DCU_INT_MASK failed\n");
+ ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
+ DCU_UPDATE_MODE_READREG);
+ if (ret)
+ dev_err(&pdev->dev, "set DCU_UPDATE_MODE failed\n");
+
+ return 0;
+}
+
+static int fsl_dcu_load(struct drm_device *ddev, unsigned long flags)
+{
+ struct device *dev = ddev->dev;
+ struct platform_device *pdev = to_platform_device(dev);
+ struct fsl_dcu_drm_device *fsl_dev;
+ struct resource *res;
+ void __iomem *base;
+ int ret;
+
+ fsl_dev = devm_kzalloc(dev, sizeof(*fsl_dev), GFP_KERNEL);
+ if (!fsl_dev)
+ return -ENOMEM;
+
+ fsl_dev->dev = dev;
+ fsl_dev->ddev = ddev;
+ fsl_dev->np = dev->of_node;
+ ddev->dev_private = fsl_dev;
+ dev_set_drvdata(dev, fsl_dev);
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(dev, "could not get memory IO resource\n");
+ return -ENODEV;
+ }
+
+ base = devm_ioremap_resource(dev, res);
+ if (IS_ERR(base)) {
+ ret = PTR_ERR(base);
+ return ret;
+ }
+
+ fsl_dev->clk = devm_clk_get(dev, "dcu");
+ if (IS_ERR(fsl_dev->clk)) {
+ ret = PTR_ERR(fsl_dev->clk);
+ dev_err(dev, "failed to get dcu clock\n");
+ return ret;
+ }
+ ret = clk_prepare(fsl_dev->clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to prepare dcu clk\n");
+ return ret;
+ }
+ ret = clk_enable(fsl_dev->clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable dcu clk\n");
+ clk_unprepare(fsl_dev->clk);
+ return ret;
+ }
+
+ fsl_dev->regmap = devm_regmap_init_mmio(dev, base,
+ &fsl_dcu_regmap_config);
+ if (IS_ERR(fsl_dev->regmap)) {
+ dev_err(dev, "regmap init failed\n");
+ return PTR_ERR(fsl_dev->regmap);
+ }
+
+ /* Put TCON in bypass mode, so the input signals from DCU are passed
+ * through TCON unchanged */
+ fsl_dcu_bypass_tcon(fsl_dev, fsl_dev->np);
+
+ if (of_device_is_compatible(fsl_dev->np, "fsl,ls1021a-dcu"))
+ dcu_pixclk_enable();
+ ret = fsl_dcu_drm_modeset_init(fsl_dev);
+ if (ret < 0) {
+ dev_err(dev, "failed to initialize mode setting\n");
+ return ret;
+ }
+
+ ret = drm_vblank_init(ddev, ddev->mode_config.num_crtc);
+ if (ret < 0) {
+ dev_err(dev, "failed to initialize vblank\n");
+ goto done;
+ }
+
+ ret = fsl_dcu_drm_irq_init(ddev);
+ if (ret < 0)
+ goto done;
+
+ fsl_dcu_fbdev_init(ddev);
+
+ return 0;
+done:
+ if (ret)
+ fsl_dcu_unload(ddev);
+
+ return ret;
+}
+
+static void fsl_dcu_drm_preclose(struct drm_device *dev, struct drm_file *file)
+{
+}
+
+static irqreturn_t fsl_dcu_drm_irq(int irq, void *arg)
+{
+ struct drm_device *dev = arg;
+ struct fsl_dcu_drm_device *fsl_dev = dev->dev_private;
+ unsigned int int_status;
+ int ret;
+
+ regmap_read(fsl_dev->regmap, DCU_INT_STATUS, &int_status);
+ if (int_status & DCU_INT_STATUS_VBLANK)
+ drm_handle_vblank(dev, 0);
+
+ ret = regmap_write(fsl_dev->regmap, DCU_INT_STATUS, 0xffffffff);
+ if (ret)
+ dev_err(dev->dev, "set DCU_INT_STATUS failed\n");
+ ret = regmap_write(fsl_dev->regmap, DCU_UPDATE_MODE,
+ DCU_UPDATE_MODE_READREG);
+ if (ret)
+ dev_err(dev->dev, "set DCU_UPDATE_MODE failed\n");
+
+ return IRQ_HANDLED;
+}
+
+static int fsl_dcu_drm_enable_vblank(struct drm_device *dev, int crtc)
+{
+ return 0;
+}
+
+static void fsl_dcu_drm_disable_vblank(struct drm_device *dev, int crtc)
+{
+}
+
+static const struct file_operations fsl_dcu_drm_fops = {
+ .owner = THIS_MODULE,
+ .open = drm_open,
+ .release = drm_release,
+ .unlocked_ioctl = drm_ioctl,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = drm_compat_ioctl,
+#endif
+ .poll = drm_poll,
+ .read = drm_read,
+ .llseek = no_llseek,
+ .mmap = drm_gem_cma_mmap,
+};
+
+static struct drm_driver fsl_dcu_drm_driver = {
+ .driver_features = DRIVER_HAVE_IRQ | DRIVER_GEM | DRIVER_MODESET
+ | DRIVER_PRIME | DRIVER_ATOMIC,
+ .load = fsl_dcu_load,
+ .unload = fsl_dcu_unload,
+ .preclose = fsl_dcu_drm_preclose,
+ .irq_handler = fsl_dcu_drm_irq,
+ .get_vblank_counter = drm_vblank_count,
+ .enable_vblank = fsl_dcu_drm_enable_vblank,
+ .disable_vblank = fsl_dcu_drm_disable_vblank,
+ .gem_free_object = drm_gem_cma_free_object,
+ .gem_vm_ops = &drm_gem_cma_vm_ops,
+ .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
+ .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
+ .gem_prime_import = drm_gem_prime_import,
+ .gem_prime_export = drm_gem_prime_export,
+ .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
+ .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
+ .gem_prime_vmap = drm_gem_cma_prime_vmap,
+ .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
+ .gem_prime_mmap = drm_gem_cma_prime_mmap,
+ .dumb_create = drm_gem_cma_dumb_create,
+ .dumb_map_offset = drm_gem_cma_dumb_map_offset,
+ .dumb_destroy = drm_gem_dumb_destroy,
+ .fops = &fsl_dcu_drm_fops,
+ .name = "fsl-dcu-drm",
+ .desc = "Freescale DCU DRM",
+ .date = "20150213",
+ .major = 1,
+ .minor = 0,
+};
+
+#ifdef CONFIG_PM_SLEEP
+static void dcu_pixclk_disable(void)
+{
+ struct regmap *scfg_regmap;
+
+ scfg_regmap = syscon_regmap_lookup_by_compatible("fsl,ls1021a-scfg");
+ if (IS_ERR(scfg_regmap)) {
+ pr_err("No syscfg phandle specified\n");
+ return;
+ }
+
+ regmap_write(scfg_regmap, SCFG_PIXCLKCR, PXCK_DISABLE);
+}
+
+static int fsl_dcu_drm_pm_suspend(struct device *dev)
+{
+ struct fsl_dcu_drm_device *fsl_dev = dev_get_drvdata(dev);
+
+ if (!fsl_dev)
+ return 0;
+
+ if (of_device_is_compatible(fsl_dev->np, "fsl,ls1021a-dcu"))
+ dcu_pixclk_disable();
+
+ drm_kms_helper_poll_disable(fsl_dev->ddev);
+ regcache_cache_only(fsl_dev->regmap, true);
+ regcache_mark_dirty(fsl_dev->regmap);
+ clk_disable(fsl_dev->clk);
+
+ if (fsl_dev->tcon_regmap) {
+ regcache_cache_only(fsl_dev->tcon_regmap, true);
+ regcache_mark_dirty(fsl_dev->tcon_regmap);
+ clk_disable(fsl_dev->tcon_clk);
+ }
+
+ return 0;
+}
+
+static int fsl_dcu_drm_pm_resume(struct device *dev)
+{
+ struct fsl_dcu_drm_device *fsl_dev = dev_get_drvdata(dev);
+ int ret;
+
+ if (!fsl_dev)
+ return 0;
+
+ /* Enable clocks and restore all registers */
+ if (fsl_dev->tcon_regmap) {
+ ret = clk_enable(fsl_dev->tcon_clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable tcon clk\n");
+ clk_unprepare(fsl_dev->tcon_clk);
+ return ret;
+ }
+ regcache_cache_only(fsl_dev->tcon_regmap, false);
+ regcache_sync(fsl_dev->tcon_regmap);
+ }
+
+ ret = clk_enable(fsl_dev->clk);
+ if (ret < 0) {
+ dev_err(dev, "failed to enable dcu clk\n");
+ clk_unprepare(fsl_dev->clk);
+ return ret;
+ }
+
+ drm_kms_helper_poll_enable(fsl_dev->ddev);
+ regcache_cache_only(fsl_dev->regmap, false);
+ regcache_sync(fsl_dev->regmap);
+
+ if (of_device_is_compatible(fsl_dev->np, "fsl,ls1021a-dcu"))
+ dcu_pixclk_enable();
+
+ return 0;
+}
+#endif
+
+static const struct dev_pm_ops fsl_dcu_drm_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(fsl_dcu_drm_pm_suspend, fsl_dcu_drm_pm_resume)
+};
+
+static int fsl_dcu_drm_probe(struct platform_device *pdev)
+{
+ struct drm_driver *driver = &fsl_dcu_drm_driver;
+ struct drm_device *drm;
+ int err;
+
+ drm = drm_dev_alloc(driver, &pdev->dev);
+ if (!drm)
+ return -ENOMEM;
+
+ drm_dev_set_unique(drm, dev_name(&pdev->dev));
+
+ err = drm_dev_register(drm, 0);
+ if (err < 0)
+ goto unref;
+
+ DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", driver->name,
+ driver->major, driver->minor, driver->patchlevel,
+ driver->date, drm->primary->index);
+
+ return 0;
+
+unref:
+ drm_dev_unref(drm);
+ return err;
+}
+
+static int fsl_dcu_drm_remove(struct platform_device *pdev)
+{
+ struct fsl_dcu_drm_device *fsl_dev = platform_get_drvdata(pdev);
+
+ drm_put_dev(fsl_dev->ddev);
+
+ return 0;
+}
+
+static const struct of_device_id fsl_dcu_of_match[] = {
+ { .compatible = "fsl,ls1021a-dcu", },
+ { .compatible = "fsl,vf610-dcu", },
+ { },
+};
+MODULE_DEVICE_TABLE(of, fsl_dcu_of_match);
+
+static struct platform_driver fsl_dcu_drm_platform_driver = {
+ .probe = fsl_dcu_drm_probe,
+ .remove = fsl_dcu_drm_remove,
+ .driver = {
+ .name = "fsl,dcu",
+ .pm = &fsl_dcu_drm_pm_ops,
+ .of_match_table = fsl_dcu_of_match,
+ },
+};
+
+module_platform_driver(fsl_dcu_drm_platform_driver);
+
+MODULE_DESCRIPTION("Freescale DCU DRM Driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
new file mode 100644
index 0000000..336744e
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.h
@@ -0,0 +1,222 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __FSL_DCU_DRM_DRV_H__
+#define __FSL_DCU_DRM_DRV_H__
+
+#include <linux/kernel.h>
+#include <linux/spinlock.h>
+#include <stddef.h>
+#include <drm/drm.h>
+#include <drm/drmP.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+
+#include "fsl_dcu_drm_crtc.h"
+#include "fsl_dcu_drm_plane.h"
+#include "fsl_dcu_drm_connector.h"
+
+#define DCU_DCU_MODE 0x0010
+#define DCU_MODE_BLEND_ITER(x) ((x) << 20)
+#define DCU_MODE_RASTER_EN BIT(14)
+#define DCU_MODE_DCU_MODE(x) (x)
+#define DCU_MODE_DCU_MODE_MASK 0x03
+#define DCU_MODE_OFF 0
+#define DCU_MODE_NORMAL 1
+#define DCU_MODE_TEST 2
+#define DCU_MODE_COLORBAR 3
+
+#define DCU_BGND 0x0014
+#define DCU_BGND_R(x) ((x) << 16)
+#define DCU_BGND_G(x) ((x) << 8)
+#define DCU_BGND_B(x) (x)
+
+#define DCU_DISP_SIZE 0x0018
+#define DCU_DISP_SIZE_DELTA_Y(x) ((x) << 16)
+/*Regisiter value 1/16 of horizontal resolution*/
+#define DCU_DISP_SIZE_DELTA_X(x) ((x) >> 4)
+
+#define DCU_HSYN_PARA 0x001c
+#define DCU_HSYN_PARA_BP(x) ((x) << 22)
+#define DCU_HSYN_PARA_PW(x) ((x) << 11)
+#define DCU_HSYN_PARA_FP(x) (x)
+
+#define DCU_VSYN_PARA 0x0020
+#define DCU_VSYN_PARA_BP(x) ((x) << 22)
+#define DCU_VSYN_PARA_PW(x) ((x) << 11)
+#define DCU_VSYN_PARA_FP(x) (x)
+
+#define DCU_SYN_POL 0x0024
+#define DCU_SYN_POL_INV_PXCK_FALL (0 << 6)
+#define DCU_SYN_POL_NEG_REMAIN (0 << 5)
+#define DCU_SYN_POL_INV_VS_LOW BIT(1)
+#define DCU_SYN_POL_INV_HS_LOW BIT(0)
+
+#define DCU_THRESHOLD 0x0028
+#define DCU_THRESHOLD_LS_BF_VS(x) ((x) << 16)
+#define DCU_THRESHOLD_OUT_BUF_HIGH(x) ((x) << 8)
+#define DCU_THRESHOLD_OUT_BUF_LOW(x) (x)
+#define BF_VS_VAL 0x03
+#define BUF_MAX_VAL 0x78
+#define BUF_MIN_VAL 0x0a
+
+#define DCU_INT_STATUS 0x002C
+#define DCU_INT_STATUS_VSYNC BIT(0)
+#define DCU_INT_STATUS_UNDRUN BIT(1)
+#define DCU_INT_STATUS_LSBFVS BIT(2)
+#define DCU_INT_STATUS_VBLANK BIT(3)
+#define DCU_INT_STATUS_CRCREADY BIT(4)
+#define DCU_INT_STATUS_CRCOVERFLOW BIT(5)
+#define DCU_INT_STATUS_P1FIFOLO BIT(6)
+#define DCU_INT_STATUS_P1FIFOHI BIT(7)
+#define DCU_INT_STATUS_P2FIFOLO BIT(8)
+#define DCU_INT_STATUS_P2FIFOHI BIT(9)
+#define DCU_INT_STATUS_PROGEND BIT(10)
+#define DCU_INT_STATUS_IPMERROR BIT(11)
+#define DCU_INT_STATUS_LYRTRANS BIT(12)
+#define DCU_INT_STATUS_DMATRANS BIT(14)
+#define DCU_INT_STATUS_P3FIFOLO BIT(16)
+#define DCU_INT_STATUS_P3FIFOHI BIT(17)
+#define DCU_INT_STATUS_P4FIFOLO BIT(18)
+#define DCU_INT_STATUS_P4FIFOHI BIT(19)
+#define DCU_INT_STATUS_P1EMPTY BIT(26)
+#define DCU_INT_STATUS_P2EMPTY BIT(27)
+#define DCU_INT_STATUS_P3EMPTY BIT(28)
+#define DCU_INT_STATUS_P4EMPTY BIT(29)
+
+#define DCU_INT_MASK 0x0030
+#define DCU_INT_MASK_VSYNC BIT(0)
+#define DCU_INT_MASK_UNDRUN BIT(1)
+#define DCU_INT_MASK_LSBFVS BIT(2)
+#define DCU_INT_MASK_VBLANK BIT(3)
+#define DCU_INT_MASK_CRCREADY BIT(4)
+#define DCU_INT_MASK_CRCOVERFLOW BIT(5)
+#define DCU_INT_MASK_P1FIFOLO BIT(6)
+#define DCU_INT_MASK_P1FIFOHI BIT(7)
+#define DCU_INT_MASK_P2FIFOLO BIT(8)
+#define DCU_INT_MASK_P2FIFOHI BIT(9)
+#define DCU_INT_MASK_PROGEND BIT(10)
+#define DCU_INT_MASK_IPMERROR BIT(11)
+#define DCU_INT_MASK_LYRTRANS BIT(12)
+#define DCU_INT_MASK_DMATRANS BIT(14)
+#define DCU_INT_MASK_P3FIFOLO BIT(16)
+#define DCU_INT_MASK_P3FIFOHI BIT(17)
+#define DCU_INT_MASK_P4FIFOLO BIT(18)
+#define DCU_INT_MASK_P4FIFOHI BIT(19)
+#define DCU_INT_MASK_P1EMPTY BIT(26)
+#define DCU_INT_MASK_P2EMPTY BIT(27)
+#define DCU_INT_MASK_P3EMPTY BIT(28)
+#define DCU_INT_MASK_P4EMPTY BIT(29)
+
+#define DCU_DIV_RATIO 0x0054
+
+#define DCU_UPDATE_MODE 0x00cc
+#define DCU_UPDATE_MODE_MODE BIT(31)
+#define DCU_UPDATE_MODE_READREG BIT(30)
+
+#define DCU_DCFB_MAX 0x300
+
+#define DCU_CTRLDESCLN_1(x) (0x200 + (x) * 0x40)
+#define DCU_CTRLDESCLN_1_HEIGHT(x) ((x) << 16)
+#define DCU_CTRLDESCLN_1_WIDTH(x) (x)
+
+#define DCU_CTRLDESCLN_2(x) (0x204 + (x) * 0x40)
+#define DCU_CTRLDESCLN_2_POSY(x) ((x) << 16)
+#define DCU_CTRLDESCLN_2_POSX(x) (x)
+
+#define DCU_CTRLDESCLN_3(x) (0x208 + (x) * 0x40)
+
+#define DCU_CTRLDESCLN_4(x) (0x20c + (x) * 0x40)
+#define DCU_CTRLDESCLN_4_EN BIT(31)
+#define DCU_CTRLDESCLN_4_TILE_EN BIT(30)
+#define DCU_CTRLDESCLN_4_DATA_SEL_CLUT BIT(29)
+#define DCU_CTRLDESCLN_4_SAFETY_EN BIT(28)
+#define DCU_CTRLDESCLN_4_TRANS(x) ((x) << 20)
+#define DCU_CTRLDESCLN_4_BPP(x) ((x) << 16)
+#define DCU_CTRLDESCLN_4_RLE_EN BIT(15)
+#define DCU_CTRLDESCLN_4_LUOFFS(x) ((x) << 4)
+#define DCU_CTRLDESCLN_4_BB_ON BIT(2)
+#define DCU_CTRLDESCLN_4_AB(x) (x)
+
+#define DCU_CTRLDESCLN_5(x) (0x210 + (x) * 0x40)
+#define DCU_CTRLDESCLN_5_CKMAX_R(x) ((x) << 16)
+#define DCU_CTRLDESCLN_5_CKMAX_G(x) ((x) << 8)
+#define DCU_CTRLDESCLN_5_CKMAX_B(x) (x)
+
+#define DCU_CTRLDESCLN_6(x) (0x214 + (x) * 0x40)
+#define DCU_CTRLDESCLN_6_CKMIN_R(x) ((x) << 16)
+#define DCU_CTRLDESCLN_6_CKMIN_G(x) ((x) << 8)
+#define DCU_CTRLDESCLN_6_CKMIN_B(x) (x)
+
+#define DCU_CTRLDESCLN_7(x) (0x218 + (x) * 0x40)
+#define DCU_CTRLDESCLN_7_TILE_VER(x) ((x) << 16)
+#define DCU_CTRLDESCLN_7_TILE_HOR(x) (x)
+
+#define DCU_CTRLDESCLN_8(x) (0x21c + (x) * 0x40)
+#define DCU_CTRLDESCLN_8_FG_FCOLOR(x) (x)
+
+#define DCU_CTRLDESCLN_9(x) (0x220 + (x) * 0x40)
+#define DCU_CTRLDESCLN_9_BG_BCOLOR(x) (x)
+
+#define DCU_CTRLDESCLN_10(x) (0x224 + (x) * 0x40)
+#define DCU_CTRLDESCLN_10_POST_SKIP(x) ((x) << 16)
+#define DCU_CTRLDESCLN_10_PRE_SKIP(x) (x)
+
+#ifdef CONFIG_SOC_VF610
+#define DCU_TOTAL_LAYER_NUM 64
+#define DCU_LAYER_NUM_MAX 6
+#else
+#define DCU_TOTAL_LAYER_NUM 16
+#define DCU_LAYER_NUM_MAX 4
+#endif
+
+#define FSL_DCU_RGB565 4
+#define FSL_DCU_RGB888 5
+#define FSL_DCU_ARGB8888 6
+#define FSL_DCU_ARGB1555 11
+#define FSL_DCU_ARGB4444 12
+#define FSL_DCU_YUV422 14
+
+#define TCON_CTRL1 0x0000
+#define TCON_BYPASS_ENABLE BIT(29)
+
+#define SCFG_PIXCLKCR 0x28
+#define PXCK_ENABLE BIT(31)
+#define PXCK_DISABLE 0
+
+#define DBG(fmt, ...) DRM_DEBUG(fmt"\n", ##__VA_ARGS__)
+
+struct clk;
+struct device;
+struct drm_device;
+
+struct fsl_dcu_drm_device {
+ struct device *dev;
+ struct device_node *np;
+ struct regmap *regmap;
+ struct regmap *tcon_regmap;
+ unsigned int irq;
+ struct clk *clk;
+ struct clk *tcon_clk;
+ /*protects hardware register*/
+ spinlock_t irq_lock;
+ struct drm_device *ddev;
+ struct drm_fbdev_cma *fbdev;
+ struct drm_crtc crtc;
+ struct drm_encoder encoder;
+ struct fsl_dcu_drm_connector connector;
+};
+
+void fsl_dcu_fbdev_init(struct drm_device *dev);
+
+#endif /* __FSL_DCU_DRM_DRV_H__ */
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c
new file mode 100644
index 0000000..f8ef0e1
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_fbdev.c
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_fb_cma_helper.h>
+
+#include "fsl_dcu_drm_drv.h"
+
+/* initialize fbdev helper */
+void fsl_dcu_fbdev_init(struct drm_device *dev)
+{
+ struct fsl_dcu_drm_device *fsl_dev = dev_get_drvdata(dev->dev);
+
+ fsl_dev->fbdev = drm_fbdev_cma_init(dev, 24, 1, 1);
+}
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
new file mode 100644
index 0000000..0de21c69
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.c
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_atomic_helper.h>
+
+#include "fsl_dcu_drm_crtc.h"
+#include "fsl_dcu_drm_connector.h"
+#include "fsl_dcu_drm_drv.h"
+
+static const struct drm_mode_config_funcs fsl_dcu_drm_mode_config_funcs = {
+ .fb_create = drm_fb_cma_create,
+ .atomic_check = drm_atomic_helper_check,
+ .atomic_commit = drm_atomic_helper_commit,
+};
+
+int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev)
+{
+ drm_mode_config_init(fsl_dev->ddev);
+
+ fsl_dev->ddev->mode_config.min_width = 0;
+ fsl_dev->ddev->mode_config.min_height = 0;
+ fsl_dev->ddev->mode_config.max_width = 2031;
+ fsl_dev->ddev->mode_config.max_height = 2047;
+ fsl_dev->ddev->mode_config.funcs = &fsl_dcu_drm_mode_config_funcs;
+
+ drm_kms_helper_poll_init(fsl_dev->ddev);
+ fsl_dcu_drm_crtc_create(fsl_dev);
+ fsl_dcu_drm_encoder_create(fsl_dev, &fsl_dev->crtc);
+ fsl_dcu_drm_connector_create(fsl_dev, &fsl_dev->encoder);
+ drm_mode_config_reset(fsl_dev->ddev);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h
new file mode 100644
index 0000000..b9bd299
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_kms.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __FSL_DCU_DRM_KMS_H__
+#define __FSL_DCU_DRM_KMS_H__
+
+int fsl_dcu_drm_modeset_init(struct fsl_dcu_drm_device *fsl_dev);
+
+#endif /* __FSL_DCU_DRM_KMS_H__ */
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
new file mode 100644
index 0000000..fccb517
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * 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 <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_cma_helper.h>
+#include <drm/drm_gem_cma_helper.h>
+#include <linux/regmap.h>
+#include <drm/drm_plane_helper.h>
+#include <drm/drm_atomic_helper.h>
+
+#include "fsl_dcu_drm_drv.h"
+#include "fsl_dcu_drm_kms.h"
+#include "fsl_dcu_drm_plane.h"
+
+#define to_fsl_dcu_plane(plane) \
+ container_of(plane, struct fsl_dcu_drm_plane, plane)
+
+static int
+fsl_dcu_drm_plane_prepare_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb,
+ const struct drm_plane_state *new_state)
+{
+ return 0;
+}
+
+static void
+fsl_dcu_drm_plane_cleanup_fb(struct drm_plane *plane,
+ struct drm_framebuffer *fb,
+ const struct drm_plane_state *new_state)
+{
+}
+
+static int fsl_dcu_drm_plane_atomic_check(struct drm_plane *plane,
+ struct drm_plane_state *state)
+{
+ return 0;
+}
+
+static void fsl_dcu_drm_plane_atomic_disable(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+}
+
+void fsl_dcu_drm_plane_atomic_update(struct drm_plane *plane,
+ struct drm_plane_state *old_state)
+{
+ struct fsl_dcu_drm_device *fsl_dev = plane->dev->dev_private;
+ struct drm_plane_state *state = plane->state;
+ struct drm_framebuffer *fb = plane->state->fb;
+ struct drm_gem_cma_object *gem;
+ struct fsl_dcu_drm_plane *fsl_plane = to_fsl_dcu_plane(plane);
+ u32 index, alpha, bpp;
+ int err;
+
+ if (!fb)
+ return;
+
+ index = fsl_plane->index;
+ gem = drm_fb_cma_get_gem_obj(fb, 0);
+
+ switch (fb->pixel_format) {
+ case DRM_FORMAT_RGB565:
+ bpp = FSL_DCU_RGB565;
+ alpha = 0xff;
+ break;
+ case DRM_FORMAT_RGB888:
+ bpp = FSL_DCU_RGB888;
+ alpha = 0xff;
+ break;
+ case DRM_FORMAT_ARGB8888:
+ bpp = FSL_DCU_ARGB8888;
+ alpha = 0xff;
+ break;
+ case DRM_FORMAT_BGRA4444:
+ bpp = FSL_DCU_ARGB4444;
+ alpha = 0xff;
+ break;
+ case DRM_FORMAT_ARGB1555:
+ bpp = FSL_DCU_ARGB1555;
+ alpha = 0xff;
+ break;
+ case DRM_FORMAT_YUV422:
+ bpp = FSL_DCU_YUV422;
+ alpha = 0xff;
+ break;
+ default:
+ return;
+ }
+
+ err = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_1(index),
+ DCU_CTRLDESCLN_1_HEIGHT(state->crtc_h) |
+ DCU_CTRLDESCLN_1_WIDTH(state->crtc_w));
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_2(index),
+ DCU_CTRLDESCLN_2_POSY(state->crtc_y) |
+ DCU_CTRLDESCLN_2_POSX(state->crtc_x));
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap,
+ DCU_CTRLDESCLN_3(index), gem->paddr);
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_4(index),
+ DCU_CTRLDESCLN_4_EN |
+ DCU_CTRLDESCLN_4_TRANS(alpha) |
+ DCU_CTRLDESCLN_4_BPP(bpp) |
+ DCU_CTRLDESCLN_4_AB(0));
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_5(index),
+ DCU_CTRLDESCLN_5_CKMAX_R(0xFF) |
+ DCU_CTRLDESCLN_5_CKMAX_G(0xFF) |
+ DCU_CTRLDESCLN_5_CKMAX_B(0xFF));
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_6(index),
+ DCU_CTRLDESCLN_6_CKMIN_R(0) |
+ DCU_CTRLDESCLN_6_CKMIN_G(0) |
+ DCU_CTRLDESCLN_6_CKMIN_B(0));
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_7(index), 0);
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_8(index),
+ DCU_CTRLDESCLN_8_FG_FCOLOR(0));
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_9(index),
+ DCU_CTRLDESCLN_9_BG_BCOLOR(0));
+ if (err)
+ goto set_failed;
+ if (of_device_is_compatible(fsl_dev->np, "fsl,ls1021a-dcu")) {
+ err = regmap_write(fsl_dev->regmap, DCU_CTRLDESCLN_10(index),
+ DCU_CTRLDESCLN_10_POST_SKIP(0) |
+ DCU_CTRLDESCLN_10_PRE_SKIP(0));
+ if (err)
+ goto set_failed;
+ }
+ err = regmap_update_bits(fsl_dev->regmap, DCU_DCU_MODE,
+ DCU_MODE_DCU_MODE_MASK,
+ DCU_MODE_DCU_MODE(DCU_MODE_NORMAL));
+ if (err)
+ goto set_failed;
+ err = regmap_write(fsl_dev->regmap,
+ DCU_UPDATE_MODE, DCU_UPDATE_MODE_READREG);
+ if (err)
+ goto set_failed;
+ return;
+
+set_failed:
+ dev_err(fsl_dev->dev, "set DCU register failed\n");
+}
+
+int fsl_dcu_drm_plane_disable(struct drm_plane *plane)
+{
+ return 0;
+}
+
+void fsl_dcu_drm_plane_destroy(struct drm_plane *plane)
+{
+ fsl_dcu_drm_plane_disable(plane);
+ drm_plane_cleanup(plane);
+}
+
+static const uint32_t fsl_dcu_drm_plane_formats[] = {
+ DRM_FORMAT_RGB565,
+ DRM_FORMAT_RGB888,
+ DRM_FORMAT_ARGB8888,
+ DRM_FORMAT_ARGB4444,
+ DRM_FORMAT_ARGB1555,
+ DRM_FORMAT_YUV422,
+};
+
+static const struct drm_plane_funcs fsl_dcu_drm_plane_funcs = {
+ .update_plane = drm_atomic_helper_update_plane,
+ .disable_plane = drm_atomic_helper_disable_plane,
+ .destroy = fsl_dcu_drm_plane_destroy,
+ .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
+ .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
+ .reset = drm_atomic_helper_plane_reset,
+};
+
+static const struct drm_plane_helper_funcs fsl_dcu_drm_plane_helper_funcs = {
+ .prepare_fb = fsl_dcu_drm_plane_prepare_fb,
+ .cleanup_fb = fsl_dcu_drm_plane_cleanup_fb,
+ .atomic_check = fsl_dcu_drm_plane_atomic_check,
+ .atomic_update = fsl_dcu_drm_plane_atomic_update,
+ .atomic_disable = fsl_dcu_drm_plane_atomic_disable,
+};
+
+struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev)
+{
+ struct drm_plane *primary;
+ int ret;
+
+ primary = kzalloc(sizeof(*primary), GFP_KERNEL);
+ if (!primary) {
+ DRM_DEBUG_KMS("Failed to allocate primary plane\n");
+ return NULL;
+ }
+
+ /* possible_crtc's will be filled in later by crtc_init */
+ ret = drm_universal_plane_init(dev, primary, 0,
+ &fsl_dcu_drm_plane_funcs,
+ fsl_dcu_drm_plane_formats,
+ ARRAY_SIZE(fsl_dcu_drm_plane_formats),
+ DRM_PLANE_TYPE_PRIMARY);
+ if (ret) {
+ kfree(primary);
+ primary = NULL;
+ }
+ drm_plane_helper_add(primary, &fsl_dcu_drm_plane_helper_funcs);
+
+ return primary;
+}
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h
new file mode 100644
index 0000000..ccbfa61
--- /dev/null
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_plane.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2015 Freescale Semiconductor, Inc.
+ *
+ * Freescale DCU drm device driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef __FSL_DCU_DRM_PLANE_H__
+#define __FSL_DCU_DRM_PLANE_H__
+
+struct fsl_dcu_drm_device;
+struct fsl_dcu_drm_plane {
+ struct drm_plane plane;
+ unsigned int index;
+};
+
+struct drm_plane *fsl_dcu_drm_primary_create_plane(struct drm_device *dev);
+
+#endif /* __FSL_DCU_DRM_PLANE_H__ */
--
2.1.0.27.g96db324

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH] gpu/drm/amdgpu: Include only if CONFIG_DEBUG_FS is set (no replies)

$
0
0
We have no need to include <linux/debugfs.h> if the CONFIG_DEBUG_FS option
is not set.

Signed-off-by: Alexander Kuleshov <kuleshovmail@gmail.com>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
index ba46be3..23dbfa4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c
@@ -27,7 +27,6 @@
*/
#include <linux/console.h>
#include <linux/slab.h>
-#include <linux/debugfs.h>
#include <drm/drmP.h>
#include <drm/drm_crtc_helper.h>
#include <drm/amdgpu_drm.h>
@@ -44,2 +43,2 @@
#include "vi.h"
#include "bif/bif_4_1_d.h"

+#ifdef CONFIG_DEBUG_FS
+#include <linux/debugfs.h>
+#endif
+
static int amdgpu_debugfs_regs_init(struct amdgpu_device *adev);
static void amdgpu_debugfs_regs_cleanup(struct amdgpu_device *adev);

--
2.5.0-rc1

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH] Revert "perf tools: Allow to specify custom linker command" (no replies)

$
0
0
This reverts commit 5ef7bbb09f7b
("perf tools: Allow to specify custom linker command").

LD is a pre-defined variable in GNU Make. I.e. it is always defined.
Which means there's no point to check "LD ?= ..." because it will never
succeed. And so LD will be either that explicitly passed to make like
this:
------->8-------
make LD=path_to_my_ld ...
------->8-------
or default value, which is host's "ld".

Latter leads to failure of cross-linkage because instead of cross linker
"$(CROSS_COMPILE)ld" host's "ld" is used.

As for commit which is reverted here:
[1] Usually for selection of non-default flavour of CPU core/options
linker flags are used like "-mtune=xxx" or "-mMyCPUType" etc.

[2] Still to implement ability to use "ld" that differs from
"$(CROSS_COMPILE)ld" one will need to add new makefile variable like
TARGET_LD and then check if $(TARGET_LD) is not specified on make
invocation then use "$(CROSS_COMPILE)ld".

But for now to fix cross-building of perf this revert is enough.

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
Cc: Vineet Gupta <vgupta@synopsys.com>
Cc: Aaro Koskinen <aaro.koskinen@nokia.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Paul Mackerras <paulus@samba.org>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: linux-kernel@vger.kernel.org
---
tools/perf/Makefile.perf | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 7a4b549..0e0938a 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -110,7 +110,7 @@ $(OUTPUT)PERF-VERSION-FILE: ../../.git/HEAD
$(Q)touch $(OUTPUT)PERF-VERSION-FILE

CC = $(CROSS_COMPILE)gcc
-LD ?= $(CROSS_COMPILE)ld
+LD = $(CROSS_COMPILE)ld
AR = $(CROSS_COMPILE)ar
PKG_CONFIG = $(CROSS_COMPILE)pkg-config

--
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Applied "regmap: Add better support for devices without readback support" to the regmap tree (no replies)

$
0
0
The patch

regmap: Add better support for devices without readback support

has been applied to the regmap tree at

git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regmap.git

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From 04dc91ce2cca5927159c689aa1f47663f8c51530 Mon Sep 17 00:00:00 2001
From: Lars-Peter Clausen <lars@metafoo.de>
Date: Mon, 13 Jul 2015 12:26:44 +0200
Subject: [PATCH] regmap: Add better support for devices without readback
support

Currently regmap requires that a reg_read callback is supplied, otherwise a
warning is emitted each time regmap_read() is called. This means a device
or bus without readback support needs to supply dummy reg_read callback.
Apart from that regmap_read() will still work fine if a cache is used.

Remove the warning and let regmap_readable() return false if not reg_read
callback is supplied. This means a device no longer has to supply a dummy
callback if it does not support readback and it also doesn't have to have a
readable_reg callback that always returns false since this is now implicit.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
drivers/base/regmap/regmap.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c
index 7111d04f2621..8894b992043e 100644
--- a/drivers/base/regmap/regmap.c
+++ b/drivers/base/regmap/regmap.c
@@ -93,6 +93,9 @@ bool regmap_writeable(struct regmap *map, unsigned int reg)

bool regmap_readable(struct regmap *map, unsigned int reg)
{
+ if (!map->reg_read)
+ return false;
+
if (map->max_register && reg > map->max_register)
return false;

@@ -2097,8 +2100,6 @@ static int _regmap_read(struct regmap *map, unsigned int reg,
int ret;
void *context = _regmap_map_get_context(map);

- WARN_ON(!map->reg_read);
-
if (!map->cache_bypass) {
ret = regcache_read(map, reg, val);
if (ret == 0)
--
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Applied "regulator: da9210: Add optional interrupt support" to the regulator tree (no replies)

$
0
0
The patch

regulator: da9210: Add optional interrupt support

has been applied to the regulator tree at

git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator.git

All being well this means that it will be integrated into the linux-next
tree (usually sometime in the next 24 hours) and sent to Linus during
the next merge window (or sooner if it is a bug fix), however if
problems are discovered then the patch may be dropped or reverted.

You may get further e-mails resulting from automated or manual testing
and review of the tree, please engage with people reporting problems and
send followup patches addressing any issues that are reported if needed.

If any updates are required or you are submitting further changes they
should be sent as incremental updates against current git, existing
patches will not be replaced.

Please add any relevant lists and maintainers to the CCs when replying
to this mail.

Thanks,
Mark

From 4245746037e379dc9f1388e422d52001cd431921 Mon Sep 17 00:00:00 2001
From: Geert Uytterhoeven <geert+renesas@glider.be>
Date: Wed, 24 Jun 2015 14:14:21 +0200
Subject: [PATCH] regulator: da9210: Add optional interrupt support

Add optional interrupt support to the da9210 regulator driver, to handle
over-current, under- and over-voltage, and over-temperature events.

Only the interrupt sources for which we handle events are unmasked, to
avoid interrupts we cannot handle.

Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Signed-off-by: Mark Brown <broonie@kernel.org>
---
.../devicetree/bindings/regulator/da9210.txt | 4 ++
drivers/regulator/da9210-regulator.c | 75 ++++++++++++++++++++++
2 files changed, 79 insertions(+)

diff --git a/Documentation/devicetree/bindings/regulator/da9210.txt b/Documentation/devicetree/bindings/regulator/da9210.txt
index 3297c53cb915..7aa9b1fa6b21 100644
--- a/Documentation/devicetree/bindings/regulator/da9210.txt
+++ b/Documentation/devicetree/bindings/regulator/da9210.txt
@@ -5,6 +5,10 @@ Required properties:
- compatible: must be "dlg,da9210"
- reg: the i2c slave address of the regulator. It should be 0x68.

+Optional properties:
+
+- interrupts: a reference to the DA9210 interrupt, if available.
+
Any standard regulator properties can be used to configure the single da9210
DCDC.

diff --git a/drivers/regulator/da9210-regulator.c b/drivers/regulator/da9210-regulator.c
index f0489cb9018b..8e39f7457bc3 100644
--- a/drivers/regulator/da9210-regulator.c
+++ b/drivers/regulator/da9210-regulator.c
@@ -22,6 +22,8 @@
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/slab.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
@@ -120,6 +122,55 @@ static int da9210_get_current_limit(struct regulator_dev *rdev)
return da9210_buck_limits[sel];
}

+static irqreturn_t da9210_irq_handler(int irq, void *data)
+{
+ struct da9210 *chip = data;
+ unsigned int val, handled = 0;
+ int error, ret = IRQ_NONE;
+
+ error = regmap_read(chip->regmap, DA9210_REG_EVENT_B, &val);
+ if (error < 0)
+ goto error_i2c;
+
+ if (val & DA9210_E_OVCURR) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_OVER_CURRENT,
+ NULL);
+ handled |= DA9210_E_OVCURR;
+ }
+ if (val & DA9210_E_NPWRGOOD) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_UNDER_VOLTAGE,
+ NULL);
+ handled |= DA9210_E_NPWRGOOD;
+ }
+ if (val & (DA9210_E_TEMP_WARN | DA9210_E_TEMP_CRIT)) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_OVER_TEMP, NULL);
+ handled |= val & (DA9210_E_TEMP_WARN | DA9210_E_TEMP_CRIT);
+ }
+ if (val & DA9210_E_VMAX) {
+ regulator_notifier_call_chain(chip->rdev,
+ REGULATOR_EVENT_REGULATION_OUT,
+ NULL);
+ handled |= DA9210_E_VMAX;
+ }
+ if (handled) {
+ /* Clear handled events */
+ error = regmap_write(chip->regmap, DA9210_REG_EVENT_B, handled);
+ if (error < 0)
+ goto error_i2c;
+
+ ret = IRQ_HANDLED;
+ }
+
+ return ret;
+
+error_i2c:
+ dev_err(regmap_get_device(chip->regmap), "I2C error : %d\n", error);
+ return ret;
+}
+
/*
* I2C driver interface functions
*/
@@ -168,6 +219,30 @@ static int da9210_i2c_probe(struct i2c_client *i2c,
}

chip->rdev = rdev;
+ if (i2c->irq) {
+ error = devm_request_threaded_irq(&i2c->dev, i2c->irq, NULL,
+ da9210_irq_handler,
+ IRQF_TRIGGER_LOW |
+ IRQF_ONESHOT | IRQF_SHARED,
+ "da9210", chip);
+ if (error) {
+ dev_err(&i2c->dev, "Failed to request IRQ%u: %d\n",
+ i2c->irq, error);
+ return error;
+ }
+
+ error = regmap_update_bits(chip->regmap, DA9210_REG_MASK_B,
+ DA9210_M_OVCURR | DA9210_M_NPWRGOOD |
+ DA9210_M_TEMP_WARN |
+ DA9210_M_TEMP_CRIT | DA9210_M_VMAX, 0);
+ if (error < 0) {
+ dev_err(&i2c->dev, "Failed to update mask reg: %d\n",
+ error);
+ return error;
+ }
+ } else {
+ dev_warn(&i2c->dev, "No IRQ configured\n");
+ }

i2c_set_clientdata(i2c, chip);

--
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

[PATCH] serial: samsung: Remove redundant DEBUG_LL check (no replies)

$
0
0
Commit 84f57d9e3685 ("tty: serial/samsung: fix modular build") fixed
build issues when the driver was built as a module. One of those was
that printascii is only accessible when the driver is built-in.

But there is no need to check for defined(CONFIG_DEBUG_LL) since the
SERIAL_SAMSUNG_DEBUG Kconfig symbol already depends on DEBUG_LL.

Signed-off-by: Javier Martinez Canillas <javier@osg.samsung.com>

---

drivers/tty/serial/samsung.c | 1 -
1 file changed, 1 deletion(-)

diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index 67d0c213b1c7..8c963d6d9074 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -53,7 +53,6 @@
#include "samsung.h"

#if defined(CONFIG_SERIAL_SAMSUNG_DEBUG) && \
- defined(CONFIG_DEBUG_LL) && \
!defined(MODULE)

extern void printascii(const char *);
--
2.4.3

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Viewing all 24115 articles
Browse latest View live