Re: staging: comedi: USB devs not working / some comedi core reorganization
On Fri, Dec 20, 2013 at 11:48:31PM +, Bernd Porr wrote: > >From 5971245d01f25890826fc05f7bab0d2b8d6bfd63 Mon Sep 17 00:00:00 2001 > From: Bernd Porr > Date: Fri, 20 Dec 2013 23:32:08 + > Subject: [PATCH 1/1] Moving un-registering of the subdevices and the main > comedi device into one function and the module which is responsible for file > operations. The kernel oops observed before was because the main device was > un-registered first and then the subdevices which were then no longer valid. > When you are doing a git commit then the first line of the commit message is the subject and then put a blank line followed by the body of the commit message. [PATCH] Staging: comedi: fix remove ordering Bla blah blah explanation. Put the warning message in the commit log as well. Really patches need to be sent inline and not as an attachment. Greg deals with too many patches and has scripts to handle inline patches and has to handle attachments manually. Everyone else has review scripts for inline patches as well. http://www.freedesktop.org/wiki/Software/PulseAudio/HowToUseGitSendEmail/ regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 30/31] staging: r8188eu: Fix sparse warnings in core/rtw_br_ext.c
A couple of these are real endian bugs, it's not just "warnings". regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 31/31] staging: r8188eu: Fix smatch error
On Sun, Dec 22, 2013 at 05:37:02PM -0600, Larry Finger wrote: > Smatch shows the following: > > CHECK drivers/staging/rtl8188eu/core/rtw_mlme_ext.c > drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:1401 OnAssocReq() error: buffer > overflow 'pstapriv->sta_aid' 32 <= 32 > This is a false positive in Smatch. Don't do work arounds for buggy tools. If you have the cross function database built on the latest version of Smatch then I think it understands the code correctly and doesn't print a warning. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 24/31] staging: r8188eu: Additional cleanup of include/odm.h
On Sun, Dec 22, 2013 at 05:36:55PM -0600, Larry Finger wrote: > --- a/drivers/staging/rtl8188eu/include/odm_interface.h > +++ b/drivers/staging/rtl8188eu/include/odm_interface.h > @@ -51,7 +51,7 @@ ODM_REG(DIG,_pDM_Odm) > > #define _cat(_name, _ic_type, _func) \ > ( \ > - ((_ic_type) & ODM_IC_11N_SERIES) ? _func##_11N(_name) : \ > + (_ic_type) ? _func##_11N(_name) : \ > _func##_11AC(_name) \ > ) The original version of this function was more readable... I think _ic_type is either zero or 16? regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 1/3] mfd: Add realtek USB card reader driver
On Mon, Dec 23, 2013 at 05:52:05PM +0800, rogera...@realtek.com wrote: > +static int rtsx_usb_seq_write_register(struct rtsx_ucr *ucr, > + u16 addr, u16 len, u8 *data) > +{ > + u16 cmd_len = len + 12; > + > + if (data == NULL) > + return -EINVAL; > + > + cmd_len = (cmd_len <= CMD_BUF_LEN) ? cmd_len : CMD_BUF_LEN; > + I do not like how you have three names for the same buffer length. > +#define IOBUF_SIZE 1024 > +#define CMD_BUF_LEN 1024 > +#define RSP_BUF_LEN 1024 The buffer is allocated as IOBUF_SIZE and then CMD_BUF_LEN is used as a limiter here and one other place. RSP_BUF_LEN is not used at all. > + if (cmd_len % 4) > + cmd_len += (4 - cmd_len % 4); > + > + > + ucr->cmd_buf[0] = 'R'; > + ucr->cmd_buf[1] = 'T'; > + ucr->cmd_buf[2] = 'C'; > + ucr->cmd_buf[3] = 'R'; > + ucr->cmd_buf[PACKET_TYPE] = SEQ_WRITE; > + ucr->cmd_buf[5] = (u8)(len >> 8); > + ucr->cmd_buf[6] = (u8)len; > + ucr->cmd_buf[STAGE_FLAG] = 0; > + ucr->cmd_buf[8] = (u8)(addr >> 8); > + ucr->cmd_buf[9] = (u8)addr; > + > + memcpy(ucr->cmd_buf + 12, data, len); Buffer overflow here because ->cmd_buf is only IOBUF_SIZE long. Probably the earlier two uses of "len" are buffer overflows as well. > +int rtsx_usb_ep0_write_register(struct rtsx_ucr *ucr, u16 addr, > + u8 mask, u8 data) > +{ > + u16 value = 0, index = 0; > + > + value |= (u16)(3 & 0x03) << 14; > + value |= (u16)(addr & 0x3FFF); Don't do pointless things: value |= 0x03 << 14; value |= addr & 0x3FFF; > + value = ((value << 8) & 0xFF00) | ((value >> 8) & 0x00FF); This is an endian conversion? It is buggy. Use the kernel endian conversion functions cpu_to_le16(). > + index |= (u16)mask; > + index |= (u16)data << 8; > + > + return usb_control_msg(ucr->pusb_dev, > + usb_sndctrlpipe(ucr->pusb_dev, 0), 0, 0x40, > + value, index, NULL, 0, 100); > +} > +EXPORT_SYMBOL_GPL(rtsx_usb_ep0_write_register); > + > +int rtsx_usb_ep0_read_register(struct rtsx_ucr *ucr, u16 addr, u8 *data) > +{ > + u16 value = 0; > + > + if (data == NULL) > + return -EINVAL; > + *data = 0; > + > + value |= (u16)(2 & 0x03) << 14; > + value |= (u16)(addr & 0x3FFF); > + value = ((value << 8) & 0xFF00) | ((value >> 8) & 0x00FF); same. The rest of my comments below are minor white space nits. > + > + return usb_control_msg(ucr->pusb_dev, > + usb_rcvctrlpipe(ucr->pusb_dev, 0), 0, 0xC0, > + value, 0, data, 1, 100); > +} > +EXPORT_SYMBOL_GPL(rtsx_usb_ep0_read_register); > + > +void rtsx_usb_add_cmd(struct rtsx_ucr *ucr, > + u8 cmd_type, > + u16 reg_addr, > + u8 mask, > + u8 data) > +{ > + int i; > + > + if (ucr->cmd_idx < ((CMD_BUF_LEN - CMD_OFFSET) / 4)) { > + i = CMD_OFFSET + ucr->cmd_idx * 4; > + > + ucr->cmd_buf[i++] = ((cmd_type & 0x03) << 6) | > + (u8)((reg_addr >> 8) & 0x3F); > + ucr->cmd_buf[i++] = (u8)reg_addr; > + ucr->cmd_buf[i++] = mask; > + ucr->cmd_buf[i++] = data; > + > + ucr->cmd_idx++; > + } > +} > +EXPORT_SYMBOL_GPL(rtsx_usb_add_cmd); > + > +int rtsx_usb_send_cmd(struct rtsx_ucr *ucr, u8 flag, int timeout) > +{ > + int ret; > + > + ucr->cmd_buf[CNT_H] = (u8)(ucr->cmd_idx >> 8); > + ucr->cmd_buf[CNT_L] = (u8)(ucr->cmd_idx); > + ucr->cmd_buf[STAGE_FLAG] = flag; > + > + ret = rtsx_usb_transfer_data(ucr, > + usb_sndbulkpipe(ucr->pusb_dev, EP_BULK_OUT), > + ucr->cmd_buf, ucr->cmd_idx * 4 + CMD_OFFSET, > + 0, NULL, timeout); > + if (ret) { > + /* clear HW error*/ > + rtsx_usb_ep0_write_register(ucr, SFSM_ED, 0xf8, 0xf8); Make this into a function and remove the comment. rtsx_usb_ep0_clear_hw_error(ucr); > + return ret; > + } > + > + return 0; > +} > +EXPORT_SYMBOL_GPL(rtsx_usb_send_cmd); > + > +int rtsx_usb_get_rsp(struct rtsx_ucr *ucr, int rsp_len, int timeout) > +{ > + if (rsp_len <= 0) > + return -EINVAL; > + > + if (rsp_len % 4) > + rsp_len += (4 - rsp_len % 4); > + > + return rtsx_usb_transfer_data(ucr, > + usb_rcvbulkpipe(ucr->pusb_dev, EP_BULK_IN), > + ucr->rsp_buf, rsp_len, 0, NULL, timeout); > +} > +EXPORT_SYMBOL_GPL(rtsx_usb_get_rsp); > + > +static int rtsx_usb_get_status_with_bulk(struct rtsx_ucr *ucr, u16 *status) > +{ > + int ret; > + > + rtsx_usb_init_cmd(ucr); > + rtsx_usb_add_cmd(ucr, READ_REG_CMD, CARD_EXIST, 0x00, 0x00); > + rtsx_usb_add_cmd(ucr, READ_REG_CMD, OCPSTAT, 0x00, 0x00); > + ret = rtsx_usb_send_cmd(ucr, MODE_CR, 100); > + if (ret) > + return ret; > + > +
Re: [PATCH] staging: usbip: add support for viewing imported devices
-Werror=unused-parameter is stupid. Better to turn it off instead of ugly work arounds. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: staging: comedi: USB devs not working / some comedi core reorganization
Hi Dan, see my re-submission of these patches. I did that properly with the git email this time. Hope that's now all properly formatted. Thanks also for the link. Best, /Bernd Dan Carpenter wrote: On Fri, Dec 20, 2013 at 11:48:31PM +, Bernd Porr wrote: >From 5971245d01f25890826fc05f7bab0d2b8d6bfd63 Mon Sep 17 00:00:00 2001 From: Bernd Porr Date: Fri, 20 Dec 2013 23:32:08 + Subject: [PATCH 1/1] Moving un-registering of the subdevices and the main comedi device into one function and the module which is responsible for file operations. The kernel oops observed before was because the main device was un-registered first and then the subdevices which were then no longer valid. When you are doing a git commit then the first line of the commit message is the subject and then put a blank line followed by the body of the commit message. [PATCH] Staging: comedi: fix remove ordering Bla blah blah explanation. Put the warning message in the commit log as well. Really patches need to be sent inline and not as an attachment. Greg deals with too many patches and has scripts to handle inline patches and has to handle attachments manually. Everyone else has review scripts for inline patches as well. http://www.freedesktop.org/wiki/Software/PulseAudio/HowToUseGitSendEmail/ regards, dan carpenter -- http://www.berndporr.me.uk http://www.linux-usb-daq.co.uk http://www.imdb.com/name/nm3293421/ +44 (0)7840 340069 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH, RFC 00/30] sleep_on removal
The functions sleep_on, sleep_on_timeout, interruptible_sleep_on and interruptible_sleep_on_timeout have been deprecated for as long as I can remember, and a number of people have contributed patches in the past to remove them from various drivers. This has recently popped up again and I decided to spend some of my time on tracking down the last users and kill it for good. The work is somewhat related to the BKL removal I did a couple of years ago, since most of these drivers were using the BKL in a way that actually made the sleep_on function safe to call. As the BKL was converted into mutexes, the semantics changed slightly and typically opened up a race between checking a condition and going to sleep. I don't have any of the hardware that I'm sending the patches for, so it would be great if someone could test them before they get applied. Otherwise please review very carefully. I'm definitely happy for any patches to go into maintainer trees right away. Obviously the final patch cannot go in until everything else gets merged first and I suspect there will be a series of patches for maintainerless drivers that will go along with it. Arnd Arnd Bergmann (30): ataflop: fix sleep_on races scsi: atari_scsi: fix sleep_on race DAC960: remove sleep_on usage swim3: fix interruptible_sleep_on race [media] omap_vout: avoid sleep_on race [media] usbvision: remove bogus sleep_on_timeout [media] radio-cadet: avoid interruptible_sleep_on race [media] arv: fix sleep_on race staging: serqt_usb2: don't use sleep_on staging: gdm72xx: fix interruptible_sleep_on race staging: panel: fix interruptible_sleep_on race parport: fix interruptible_sleep_on race cris: sync_serial: remove interruptible_sleep_on tty/amiserial: avoid interruptible_sleep_on usbserial: stop using interruptible_sleep_on tty: synclink: avoid sleep_on race atm: nicstar: remove interruptible_sleep_on_timeout atm: firestream: fix interruptible_sleep_on race isdn: pcbit: fix interruptible_sleep_on race isdn: hisax/elsa: fix sleep_on race in elsa FSM isdn: divert, hysdn: fix interruptible_sleep_on race isdn: fix multiple sleep_on races oss: msnd_pinnacle: avoid interruptible_sleep_on_timeout oss: midibuf: fix sleep_on races oss: vwsnd: avoid interruptible_sleep_on oss: dmasound: kill SLEEP() macro to avoid race oss: remove last sleep_on users sgi-xp: open-code interruptible_sleep_on_timeout char: nwbutton: open-code interruptible_sleep_on sched: remove sleep_on() and friends Documentation/DocBook/kernel-hacking.tmpl| 10 -- arch/cris/arch-v10/drivers/sync_serial.c | 4 ++- arch/cris/arch-v32/drivers/sync_serial.c | 4 ++- drivers/atm/firestream.c | 4 +-- drivers/atm/nicstar.c| 13 drivers/block/DAC960.c | 34 +-- drivers/block/ataflop.c | 16 - drivers/block/swim3.c| 18 ++ drivers/char/nwbutton.c | 5 ++- drivers/char/pcmcia/synclink_cs.c| 4 +-- drivers/isdn/divert/divert_procfs.c | 7 ++-- drivers/isdn/hisax/elsa.c| 9 +++-- drivers/isdn/hisax/elsa_ser.c| 3 +- drivers/isdn/hysdn/hysdn_proclog.c | 7 ++-- drivers/isdn/i4l/isdn_common.c | 13 +--- drivers/isdn/pcbit/drv.c | 6 ++-- drivers/media/platform/arv.c | 4 +-- drivers/media/platform/omap/omap_vout_vrfb.c | 3 +- drivers/media/radio/radio-cadet.c| 12 +-- drivers/media/usb/usbvision/usbvision.h | 4 +-- drivers/misc/sgi-xp/xpc_channel.c| 5 ++- drivers/parport/share.c | 3 +- drivers/scsi/atari_scsi.c| 12 +-- drivers/staging/gdm72xx/gdm_usb.c| 5 +-- drivers/staging/panel/panel.c| 4 +-- drivers/staging/serqt_usb2/serqt_usb2.c | 17 -- drivers/tty/amiserial.c | 26 ++- drivers/tty/synclink.c | 4 +-- drivers/tty/synclink_gt.c| 4 +-- drivers/tty/synclinkmp.c | 4 +-- drivers/usb/serial/ch341.c | 29 +++- drivers/usb/serial/cypress_m8.c | 49 ++-- drivers/usb/serial/f81232.c | 29 +++- drivers/usb/serial/pl2303.c | 29 +++- include/linux/wait.h | 11 --- kernel/sched/core.c | 46 -- sound/oss/dmabuf.c | 14 sound/oss/dmasound/dmasound.h| 1 - sound/oss/dmasound/dmasound_core.c | 28 +++- sound/oss/midibuf.c | 18 +- sound/oss/msnd_pinnacle.c| 31 ++ sound
[PATCH, RFC 09/30] staging: serqt_usb2: don't use sleep_on
sleep_on and related functions are going away and should not be used in this driver any more. This removes the call to interruptible_sleep_on for a wait queue that is never woken up, and replaces an interruptible_sleep_on_timeout call with the equivalent wait_event_interruptible_timeout() to avoid a small race. Both call sites still look fishy and need more work. Signed-off-by: Arnd Bergmann Cc: Greg Kroah-Hartman Cc: de...@driverdev.osuosl.org Cc: Bill Pemberton --- drivers/staging/serqt_usb2/serqt_usb2.c | 17 +++-- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/drivers/staging/serqt_usb2/serqt_usb2.c b/drivers/staging/serqt_usb2/serqt_usb2.c index 73fc3cc..e0c209e 100644 --- a/drivers/staging/serqt_usb2/serqt_usb2.c +++ b/drivers/staging/serqt_usb2/serqt_usb2.c @@ -970,17 +970,11 @@ static void qt_block_until_empty(struct tty_struct *tty, { int timeout = HZ / 10; int wait = 30; - int count; - - while (1) { - - count = qt_chars_in_buffer(tty); - - if (count <= 0) - return; - - interruptible_sleep_on_timeout(&qt_port->wait, timeout); + /* returns if we get a signal, an error, or the buffer is empty */ + while (wait_event_interruptible_timeout(qt_port->wait, + qt_chars_in_buffer(tty) <= 0, + timeout) == 0) { wait--; if (wait == 0) { dev_dbg(&qt_port->port->dev, "%s - TIMEOUT", __func__); @@ -1137,7 +1131,10 @@ static int qt_ioctl(struct tty_struct *tty, if (cmd == TIOCMIWAIT) { while (qt_port != NULL) { +#if 0 + /* this never wakes up */ interruptible_sleep_on(&qt_port->msr_wait); +#endif if (signal_pending(current)) return -ERESTARTSYS; else { -- 1.8.3.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH, RFC 10/30] staging: gdm72xx: fix interruptible_sleep_on race
interruptible_sleep_on is racy and going away. This replaces the use in the gdm72xx driver with the appropriate wait_event_interruptible_lock_irq. Signed-off-by: Arnd Bergmann Cc: Greg Kroah-Hartman Cc: de...@driverdev.osuosl.org --- drivers/staging/gdm72xx/gdm_usb.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/drivers/staging/gdm72xx/gdm_usb.c b/drivers/staging/gdm72xx/gdm_usb.c index e0cb2ff..f8788bf 100644 --- a/drivers/staging/gdm72xx/gdm_usb.c +++ b/drivers/staging/gdm72xx/gdm_usb.c @@ -780,9 +780,10 @@ static int k_mode_thread(void *arg) spin_lock_irqsave(&k_lock, flags2); } + wait_event_interruptible_lock_irq(k_wait, + !list_empty(&k_list) || k_mode_stop, + k_lock); spin_unlock_irqrestore(&k_lock, flags2); - - interruptible_sleep_on(&k_wait); } return 0; } -- 1.8.3.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH, RFC 11/30] staging: panel: fix interruptible_sleep_on race
interruptible_sleep_on is racy and going away. This replaces the one caller in the panel driver with the appropriate wait_event_interruptible variant. Signed-off-by: Arnd Bergmann Cc: de...@driverdev.osuosl.org Cc: Willy Tarreau Cc: Greg Kroah-Hartman --- drivers/staging/panel/panel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/panel/panel.c b/drivers/staging/panel/panel.c index cbc15c1..ec4b1fd 100644 --- a/drivers/staging/panel/panel.c +++ b/drivers/staging/panel/panel.c @@ -1590,8 +1590,8 @@ static ssize_t keypad_read(struct file *file, if (file->f_flags & O_NONBLOCK) return -EAGAIN; - interruptible_sleep_on(&keypad_read_wait); - if (signal_pending(current)) + if (wait_event_interruptible(keypad_read_wait, +keypad_buflen != 0)) return -EINTR; } -- 1.8.3.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] Staging: comedi: replace printk() calls with dev_dbg() in pcmmio.c
On Sat, Dec 28, 2013 at 03:13:52AM -0600, Chase Southwood wrote: > From: Chase Southwood We get this from your email. It's not needed unless you are forwarding a patch from someone else. > > This is a patch for pcmmio.c that changes several printk() calls to dev_dbg() > or dev_err() to fix checkpatch.pl warnings. Patched from 3.13-rc5. Line wrap the description at 72 characters. Don't put "Patched from 3.13-rc5." in the patch description because we don't want it to be a part of the permanent change description. Also you should be doing these against linux-next anyway. > > Signed-off-by: Chase Southwood > --- > drivers/staging/comedi/drivers/pcmmio.c | 23 +-- > 1 file changed, 13 insertions(+), 10 deletions(-) > > diff --git a/drivers/staging/comedi/drivers/pcmmio.c > b/drivers/staging/comedi/drivers/pcmmio.c > index 14cee3a..8a567c9 100644 > --- a/drivers/staging/comedi/drivers/pcmmio.c > +++ b/drivers/staging/comedi/drivers/pcmmio.c > @@ -252,7 +252,8 @@ static int pcmmio_dio_insn_bits(struct comedi_device *dev, > > #ifdef DAMMIT_ITS_BROKEN > /* DEBUG */ > - printk(KERN_DEBUG "write mask: %08x data: %08x\n", data[0], data[1]); > + dev_dbg(dev->class_dev, "write mask: %08x data: %08x\n", > + data[0], data[1]); Just delete everything to do with DAMMIT_ITS_BROKEN. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2] staging: imx-drm: imx-tve: Fix a sparse warning
On Tue, Dec 24, 2013 at 10:17:44AM +0800, Liu Ying wrote: > This patch declares the function of_get_tve_mode > as a static one to fix this sparse warning: > drivers/staging/imx-drm/imx-tve.c:563:11: warning: \ > symbol 'of_get_tve_mode' was not declared. \ > Should it be static? > > Acked-by: Shawn Guo > Signed-off-by: Liu Ying > --- > Changes from v2: > -Just added Shawn Guo's ack. No need to do that. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[patch] [media] staging: sn9c102: add a USB depend to the Kconfig
This driver won't link without USB support. Reported-by: Jim Davis Signed-off-by: Dan Carpenter diff --git a/drivers/staging/media/sn9c102/Kconfig b/drivers/staging/media/sn9c102/Kconfig index d8ae2354b626..3ab9c81173da 100644 --- a/drivers/staging/media/sn9c102/Kconfig +++ b/drivers/staging/media/sn9c102/Kconfig @@ -1,6 +1,6 @@ config USB_SN9C102 tristate "USB SN9C1xx PC Camera Controller support (DEPRECATED)" - depends on VIDEO_V4L2 + depends on USB && VIDEO_V4L2 ---help--- This driver is DEPRECATED, please use the gspca sonixb and sonixj modules instead. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] Staging: tidspbridge: Use hashtable implementation
Minor nits. Nothing major. On Wed, Dec 25, 2013 at 07:29:52PM +0200, Ivaylo DImitrov wrote: > From: Ivaylo Dimitrov > > Use upstream hashtable implementation instead of generic code > > Signed-off-by: Ivaylo Dimitrov Send from the same email you are using to Sign so we can at least verify that small thing. > --- > drivers/staging/tidspbridge/gen/gh.c | 141 > +++- > drivers/staging/tidspbridge/include/dspbridge/gh.h |6 +- > drivers/staging/tidspbridge/pmgr/dbll.c| 47 --- > 3 files changed, 78 insertions(+), 116 deletions(-) > > diff --git a/drivers/staging/tidspbridge/gen/gh.c > b/drivers/staging/tidspbridge/gen/gh.c > index 25eaef7..41a0a4f 100644 > --- a/drivers/staging/tidspbridge/gen/gh.c > +++ b/drivers/staging/tidspbridge/gen/gh.c > @@ -14,56 +14,46 @@ > * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. > */ > > -#include > +#include > +#include > +#include > > -#include > -#include > - > -struct element { > - struct element *next; > +struct gh_node { > + struct hlist_node hl; > u8 data[1]; Use a zero size array here so that you can remove the " - 1" from "sizeof(struct gh_node) - 1 + hash_tab->val_size". (Fix in later patches). > }; > > +#define GH_HASH_ORDER 8 > + > struct gh_t_hash_tab { > - u16 max_bucket; > - u16 val_size; > - struct element **buckets; > - u16(*hash) (void *, u16); > - bool(*match) (void *, void *); > - void (*delete) (void *); > + u32 val_size; > + DECLARE_HASHTABLE(hash_table, GH_HASH_ORDER); > + u32 (*hash)(void *); > + bool (*match)(void *, void *); > + void (*delete)(void *); > }; > > -static void noop(void *p); > - > /* > * gh_create > */ > > -struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 val_size, > - u16(*hash) (void *, u16), bool(*match) (void *, > - void *), > - void (*delete) (void *)) > +struct gh_t_hash_tab *gh_create(u32 val_size,u32 (*hash)(void *), > + bool (*match)(void *, void *), > + void (*delete)(void *)) > { > struct gh_t_hash_tab *hash_tab; > - u16 i; > + > hash_tab = kzalloc(sizeof(struct gh_t_hash_tab), GFP_KERNEL); > - if (hash_tab == NULL) > - return NULL; > - hash_tab->max_bucket = max_bucket; > + Don't put a blank line here between the call and the error handling. > + if (!hash_tab) > + return ERR_PTR(-ENOMEM); > + > + hash_init(hash_tab->hash_table); > + > hash_tab->val_size = val_size; > hash_tab->hash = hash; > hash_tab->match = match; > - hash_tab->delete = delete == NULL ? noop : delete; > - > - hash_tab->buckets = > - kzalloc(sizeof(struct element *) * max_bucket, GFP_KERNEL); > - if (hash_tab->buckets == NULL) { > - gh_delete(hash_tab); > - return NULL; > - } > - > - for (i = 0; i < max_bucket; i++) > - hash_tab->buckets[i] = NULL; > + hash_tab->delete = delete; > > return hash_tab; > } > @@ -73,21 +63,16 @@ struct gh_t_hash_tab *gh_create(u16 max_bucket, u16 > val_size, > */ > void gh_delete(struct gh_t_hash_tab *hash_tab) > { > - struct element *elem, *next; > - u16 i; > - > - if (hash_tab != NULL) { > - if (hash_tab->buckets != NULL) { > - for (i = 0; i < hash_tab->max_bucket; i++) { > - for (elem = hash_tab->buckets[i]; elem != NULL; > - elem = next) { > - next = elem->next; > - (*hash_tab->delete) (elem->data); > - kfree(elem); > - } > - } > - > - kfree(hash_tab->buckets); > + struct gh_node *n; > + struct hlist_node *tmp; > + u32 i; > + > + if (hash_tab) { > + hash_for_each_safe(hash_tab->hash_table, i, tmp, n, hl) { > + hash_del(&n->hl); > + if(hash_tab->delete) Use checkpatch.pl. > + hash_tab->delete(n->data); > + kfree(n); > } > > kfree(hash_tab); > @@ -100,16 +85,14 @@ void gh_delete(struct gh_t_hash_tab *hash_tab) > > void *gh_find(struct gh_t_hash_tab *hash_tab, void *key) > { > - struct element *elem; > - > - elem = hash_tab->buckets[(*hash_tab->hash) (key, hash_tab->max_bucket)]; > + struct gh_node *n; > + u32 key_hash = hash_tab->hash(key); > > - for (; elem; elem = elem->next) { > - if ((*hash_tab->match) (key, elem->data)) > - return elem->data; > - } > + hash_for_each_possible(hash_tab->hash_table, n, hl, key
Re: [PATCH 10/11] Staging: vt6656: Combined nested conditions
On Thu, Dec 26, 2013 at 07:55:39PM +0100, Sebastian Rachuj wrote: > - if (pbyDesireSSID != NULL) { > - if (((PWLAN_IE_SSID) pbyDesireSSID)->len != 0) > - pSSID = (PWLAN_IE_SSID) pbyDesireSSID; > - } > + if ((pbyDesireSSID != NULL) && > + (((PWLAN_IE_SSID) pbyDesireSSID)->len != 0)) > + pSSID = (PWLAN_IE_SSID) pbyDesireSSID; That's a lot of extra parentheses! This patch is fine, but for future reference, adding a double negative " != NULL" almost never doesn't makes the code less readable. If we remove it then this fits on one line. if (pbyDesireSSID && ((PWLAN_IE_SSID) pbyDesireSSID)->len != 0) pSSID = (PWLAN_IE_SSID) pbyDesireSSID; The casting is horrible and this is garbage staging code. If the types were cleaned up then it would look like: if (pbyDesireSSID && pbyDesireSSID->len != 0) pSSID = pbyDesireSSID; The naming is also totally bogus, of course. What does "pby" mean? I think "Desire" is clear but I don't think it's native English. The "p" in "pSSID" probably stands for pointer??? It's as if someone deliberately made every single character of this code as terrible as can be. if (new_ssid && new_ssid->len != 0) ssid = new_ssid; Technically " != 0" is the same as " != NULL" but " != 0" tells a story and makes the code more readable. > + } else if ((pMgmt->eConfigMode == > WMAC_CONFIG_AUTO) || > + ((pMgmt->eConfigMode == > WMAC_CONFIG_IBSS_STA) && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) || > + ((pMgmt->eConfigMode == > WMAC_CONFIG_ESS_STA) && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo))) { Adding all these extra parentheses makes it harder to tell which are needed and which are noise. } else if (pMgmt->eConfigMode == WMAC_CONFIG_AUTO || (pMgmt->eConfigMode == WMAC_CONFIG_IBSS_STA && WLAN_GET_CAP_INFO_IBSS(pCurrBSS->wCapInfo)) || (pMgmt->eConfigMode == WMAC_CONFIG_ESS_STA && WLAN_GET_CAP_INFO_ESS(pCurrBSS->wCapInfo)) { In this case, the extra parentheses were there in the original code but there are other times where this patch adds a number of pretty bogus parens. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 7/7] vt6655: Fixed most of the checkpatch warnings in wmgr
On Mon, Dec 30, 2013 at 03:52:37PM +0100, Michael Gunselmann wrote: > wmgr.h: Fixed checkpatch errors. > Four typedef warnings remain. > line 85: This typedef increases understandability >so this warning is not touched. > line 196, 203 and 214: >These typedef-errors might be fixed in a >later commit. Fixing them makes it necessary >to touch many other files of the driver >using this typedef. > > wmgr.c: Fixed checkpatch errors (mostly comments and braces) > Long lines were ignored and will be fixed in a later commit. > Seven warnings remain: > line 562, 770 and 921: > When removing the braces checkpatch complains > about the compiler is running into trouble. > So these lines are not touched. > line 713, 865, 1618 and 2163: > Checkpatch complains about not using netdev_dbg > instead of printk. > These warnings will be fixed in a later commit. > Don't list the things which you don't change. We're not interested in that. This patch does too many changes at once. If you want to fix all all the "checkpatch warnings" and your diff is around 20 lines long then that counts as doing one thing per patch. If the diffstat is over a thousand lines long like in this patch then it can't be a grab bag of random things all munged together in one gigantor patch. This patch mindlessly updates comment style. If we wanted that we could script it. > -//2008-8-4 by chester > +/* 2008-8-4 by chester */ Delete these. We have proper version control now. > - DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d \n", > + DBG_PRT(MSG_LEVEL_INFO, KERN_INFO "Max Support rate = %d\n", > pMgmt->sNodeDBTable[uNodeIndex].wMaxSuppRate); > - }//else { TODO: received STA under state1 handle } > - else { > - return; > } > + /* else { TODO: received STA under state1 handle } */ > + else > + return; This isn't right. The correct style is: } else { return; } But even better would be to reverse the condition and pull everything in one indent level. if (pMgmt->sNodeDBTable[uNodeIndex].eNodeState < NODE_AUTH) return; pMgmt->sNodeDBTable[uNodeIndex].eNodeState = NODE_ASSOC; pMgmt->sNodeDBTable[uNodeIndex].wCapInfo = cpu_to_le16(*sFrame.pwCapInfo); etc... > @@ -1384,11 +1369,12 @@ s_vMgrRxAuthenSequence_2( > s_vMgrLogStatus(pMgmt, > cpu_to_le16((*(pFrame->pwStatus; > pMgmt->eCurrState = WMAC_STATE_IDLE; > } > - if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) { > -//spin_unlock_irq(&pDevice->lock); > -//vCommandTimerWait((void *)pDevice, 0); > -//spin_lock_irq(&pDevice->lock); > - } > +/* if (pDevice->eCommandState == WLAN_AUTHENTICATE_WAIT) { > + *spin_unlock_irq(&pDevice->lock); > + *vCommandTimerWait((void *)pDevice, 0); > + *spin_lock_irq(&pDevice->lock); > + * } > + */ > Just delete this sort of thing instead of updating the comment style. There are a couple other examples of this as well. Please redo this patch. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2] Staging: tidspbridge: Use hashtable implementation
> + u32 val_size; > + DECLARE_HASHTABLE(hash_table, GH_HASH_ORDER); > + u32 (*hash)(void *); > + bool (*match)(void *, void *); > + void (*delete)(void *); I forgot to say, put the parameter name in the declaration. + u32 (*hash)(void *key); + bool (*match)(void *key, void *result); + void (*delete)(void *key); I have no idea if those names are correct. regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: Trivial cleanups for drivers/hv/connection.c
On Tue, Dec 31, 2013 at 10:52:37PM +0100, Pavel Machek wrote: > __u32 is only useful for kernel-user interface, u32 should be enough > for kernel. Formatting was very confusing around __get_free_pages(). > The subject should say: [PATCH] hv: Trivial cleanups for drivers/hv/connection.c regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] Staging: rtl8188eu: Fixed coding style issues
Fixed indentation coding style issues on rtw_io.c Signed-off-by: Tim Jester-Pfadt --- drivers/staging/rtl8188eu/core/rtw_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_io.c b/drivers/staging/rtl8188eu/core/rtw_io.c index 10c9c65..69b408e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_io.c +++ b/drivers/staging/rtl8188eu/core/rtw_io.c @@ -205,7 +205,7 @@ void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved)); return; @@ -239,7 +239,7 @@ void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved)); return; -- 1.8.5.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] DAS1800: Fixed typeo.
Fixed foo * bar should be foo *bar. Fixed by Joe Borg r...@josephb.org --- drivers/staging/comedi/drivers/das1800.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das1800.c b/drivers/staging/comedi/drivers/das1800.c index 1880038..8fb87df 100644 --- a/drivers/staging/comedi/drivers/das1800.c +++ b/drivers/staging/comedi/drivers/das1800.c @@ -462,7 +462,7 @@ static inline uint16_t munge_bipolar_sample(const struct comedi_device *dev, return sample; } -static void munge_data(struct comedi_device *dev, uint16_t * array, +static void munge_data(struct comedi_device *dev, uint16_t *array, unsigned int num_elements) { unsigned int i; -- 1.8.5.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] DAS6042: Fixing typeo.
Fixing foo * bar should be foo *bar. Fixed by Joe Borg r...@josephb.org --- drivers/staging/comedi/drivers/das6402.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/staging/comedi/drivers/das6402.c b/drivers/staging/comedi/drivers/das6402.c index fb25cb8..37ae356 100644 --- a/drivers/staging/comedi/drivers/das6402.c +++ b/drivers/staging/comedi/drivers/das6402.c @@ -211,7 +211,7 @@ static int das6402_ai_cancel(struct comedi_device *dev, #ifdef unused static int das6402_ai_mode2(struct comedi_device *dev, - struct comedi_subdevice *s, comedi_trig * it) + struct comedi_subdevice *s, comedi_trig *it) { struct das6402_private *devpriv = dev->private; -- 1.8.5.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH] Staging: rtl8188eu: Fixed coding style issues
On 01/02/2014 11:03 AM, Tim Jester-Pfadt wrote: Fixed indentation coding style issues on rtw_io.c Signed-off-by: Tim Jester-Pfadt --- drivers/staging/rtl8188eu/core/rtw_io.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_io.c b/drivers/staging/rtl8188eu/core/rtw_io.c index 10c9c65..69b408e 100644 --- a/drivers/staging/rtl8188eu/core/rtw_io.c +++ b/drivers/staging/rtl8188eu/core/rtw_io.c @@ -205,7 +205,7 @@ void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved)); return; @@ -239,7 +239,7 @@ void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", adapter->bDriverStopped, adapter->bSurpriseRemoved)); return; Did you run checkpatch.pl on this patch? You fixed the indents on the RT_TRACE statements, but the alignment of the continuing statements is wrong. That part was correct before. Larry ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
RE: [PATCH][Resend] Staging: comedi: replace printk() calls with dev_dbg() in pcmmio.c
On Wednesday, January 01, 2014 6:55 PM, Chase Southwood wrote: > > This is a patch for pcmmio.c that changes several printk() calls to dev_dbg() > or dev_err() to > fix checkpatch.pl warnings. Patched from 3.13-rc6. > > Signed-off-by: Chase Southwood > --- > drivers/staging/comedi/drivers/pcmmio.c | 23 +-- > 1 file changed, 13 insertions(+), 10 deletions(-) Hello Chase, This was already fixed, and merged into linux-next, by commit 4bb82d647dad7be06341ffdb9f07a56a387e213f Author: H Hartley Sweeten Date: Tue Nov 26 10:21:23 2013 -0700 staging: comedi: pcmmio: remove DAMMIT_ITS_BROKEN debug Please base any comedi patches on linux-next. Regards, Hartley ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
RE: [PATCH] comedi: Humusoft MF634 and MF624 DAQ cards driver
On Monday, December 30, 2013 6:37 PM, Rostislav Lisovy wrote: > > create mode 100644 drivers/staging/comedi/drivers/mf6x4.c Hello Rostislav, As pointed out by Dan Carpenter, you need to add a change log and Signed-off-by lines to this patch. Overall this looks pretty good. Comments below. > diff --git a/drivers/staging/comedi/Kconfig b/drivers/staging/comedi/Kconfig > index bfa27e7..89e25b4 100644 > --- a/drivers/staging/comedi/Kconfig > +++ b/drivers/staging/comedi/Kconfig > @@ -884,6 +884,12 @@ config COMEDI_GSC_HPDI > To compile this driver as a module, choose M here: the module will be > called gsc_hpdi. > > +config COMEDI_MF6X4 > + tristate "Humusoft MF634 and MF624 DAQ Card support" > + ---help--- > + This driver supports both Humusoft MF634 and MF624 Data acquisition > + cards. The legacy Humusoft MF614 card is not supported. > + > config COMEDI_ICP_MULTI > tristate "Inova ICP_MULTI support" > ---help--- > diff --git a/drivers/staging/comedi/drivers/Makefile > b/drivers/staging/comedi/drivers/Makefile > index 94cbd26..9e979a9 100644 > --- a/drivers/staging/comedi/drivers/Makefile > +++ b/drivers/staging/comedi/drivers/Makefile > @@ -110,6 +110,7 @@ obj-$(CONFIG_COMEDI_NI_PCIMIO)+= ni_pcimio.o > obj-$(CONFIG_COMEDI_RTD520) += rtd520.o > obj-$(CONFIG_COMEDI_S626)+= s626.o > obj-$(CONFIG_COMEDI_SSV_DNP) += ssv_dnp.o > +obj-$(CONFIG_COMEDI_MF6X4) += mf6x4.o > > # Comedi PCMCIA drivers > obj-$(CONFIG_COMEDI_CB_DAS16_CS) += cb_das16_cs.o > diff --git a/drivers/staging/comedi/drivers/mf6x4.c > b/drivers/staging/comedi/drivers/mf6x4.c > new file mode 100644 > index 000..46c7ce5 > --- /dev/null > +++ b/drivers/staging/comedi/drivers/mf6x4.c > @@ -0,0 +1,368 @@ > +/* > + * comedi/drivers/mf6x4.c > + * Driver for Humusoft MF634 and MF624 Data acquisition cards > + * > + * COMEDI - Linux Control and Measurement Device Interface > + * Copyright (C) 2000 David A. Schleef > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > +/* > + * Driver: mf6x4 > + * Description: Humusoft MF634 and MF624 Data acquisition card driver > + * Devices: Humusoft MF634, Humusoft MF624 > + * Author: Rostislav Lisovy > + * Status: works > + * Updated: > + * Configuration Options: none > + */ > + > +#include > +#include > +#include "../comedidev.h" > + > +/* PCI Vendor ID, Device ID */ > +#define PCI_VENDOR_ID_HUMUSOFT 0x186c > +#define PCI_DEVICE_ID_MF624 0x0624 > +#define PCI_DEVICE_ID_MF634 0x0634 Please put the PCI_VENDOR_ID_* in comedidev.h with the other PCI Vendor IDs. Also, remove the PCI_DEVICE_ID_* defines and just open code the values in the pci_device_id table. The mf6x4_boardid enums provide adequate documentation. > + > +/* Registers present in BAR0 memory region */ > +#define MF624_GPIOC_reg 0x54 > + > +#define MF6X4_GPIOC_EOLC /* End Of Last Conversion */(1 << 17) > +#define MF6X4_GPIOC_LDAC /* Load DACs */ (1 << 23) > +#define MF6X4_GPIOC_DACEN(1 << 26) > + > +/* BAR1 registers */ > +#define MF6X4_DIN_reg0x10 > +#define MF6X4_DIN_mask 0xff > +#define MF6X4_DOUT_reg 0x10 > +#define MF6X4_DOUT_mask 0xff > + > +#define MF6X4_ADSTART_reg0x20 > +#define MF6X4_ADDATA_reg 0x00 > +#define MF6X4_ADDATA_mask0x3fff > +#define MF6X4_ADCTRL_reg 0x00 > +#define MF6X4_ADCTRL_mask0xff > + > +#define MF6X4_DA0_reg0x20 > +#define MF6X4_DA1_reg0x22 > +#define MF6X4_DA2_reg0x24 > +#define MF6X4_DA3_reg0x26 > +#define MF6X4_DA4_reg0x28 > +#define MF6X4_DA5_reg0x2a > +#define MF6X4_DA6_reg0x2c > +#define MF6X4_DA7_reg0x2e > +#define MF6X4_DA_mask0x3fff > +#define MF6X4_DAC_CHANN_CNT 8 > + > +/* BAR2 reg
[PATCH v2] Staging: rtl8188eu: Fixed coding style issues
Fixed indentation coding style issues on rtw_io.c Signed-off-by: Tim Jester-Pfadt --- drivers/staging/rtl8188eu/core/rtw_io.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_io.c b/drivers/staging/rtl8188eu/core/rtw_io.c index 10c9c65..6be6c50 100644 --- a/drivers/staging/rtl8188eu/core/rtw_io.c +++ b/drivers/staging/rtl8188eu/core/rtw_io.c @@ -205,9 +205,9 @@ void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, - ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", - adapter->bDriverStopped, adapter->bSurpriseRemoved)); + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, + ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", + adapter->bDriverStopped, adapter->bSurpriseRemoved)); return; } _read_mem = pintfhdl->io_ops._read_mem; @@ -239,9 +239,9 @@ void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, - ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", - adapter->bDriverStopped, adapter->bSurpriseRemoved)); + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, + ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", + adapter->bDriverStopped, adapter->bSurpriseRemoved)); return; } -- 1.8.5.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 01/46] imx-drm: imx-drm-core: use the crtc drm device for vblank
There are a couple of ways to get at the drm_device for the vblank operations. One of them is via the private imxdrm structure, the other is via the DRM crtc structure, which also stores a pointer. Use the DRM method instead of our own method. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c |6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 96e4eee344ef..9aa5eaab6539 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -142,19 +142,19 @@ EXPORT_SYMBOL_GPL(imx_drm_crtc_panel_format); int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) { - return drm_vblank_get(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe); + return drm_vblank_get(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe); } EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_get); void imx_drm_crtc_vblank_put(struct imx_drm_crtc *imx_drm_crtc) { - drm_vblank_put(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe); + drm_vblank_put(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe); } EXPORT_SYMBOL_GPL(imx_drm_crtc_vblank_put); void imx_drm_handle_vblank(struct imx_drm_crtc *imx_drm_crtc) { - drm_handle_vblank(imx_drm_crtc->imxdrm->drm, imx_drm_crtc->pipe); + drm_handle_vblank(imx_drm_crtc->crtc->dev, imx_drm_crtc->pipe); } EXPORT_SYMBOL_GPL(imx_drm_handle_vblank); -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 00/46] Preview of imx-drm cleanup series
Here is my large patch series which cleans up imx-drm, and gets it ready to move out of drivers/staging. This is a preview only. One of these patches introduces a generic helper in drivers/base which can be used by any subsystem to assemble a sub-devices together and complete the probe of a subsystem when all devices are present - and tear it down when any of those devices go away - this is patch 26. Example usage (with imx-drm) is illustrated in patches 27 through to 41. Some of this duplicates Fabio's imx-drm HDMI patch; indeed some of the changes which were fed back to Fabio are here as their individual patches. I've not updated Fabio's patch in this series since he sent an updated version to Greg for merging. I've also included here support for ALSA based HDMI audio - if you omit the new HDMI drivers from this, it gives a net reduction in LoC. Finally, the last patch attempts to resolve a problem with the way imx-drm works - but this is fundamentally unsolvable without introducing new DT properties to properly specify the mux IDs. I'm only sending this to a limited number of people for comments at present since it's a large series, and the selection of people from maintainers is rather large. arch/arm/boot/dts/imx51-babbage.dts | 10 +- arch/arm/boot/dts/imx53-m53evk.dts |8 +- arch/arm/boot/dts/imx53-mba53.dts |6 + arch/arm/boot/dts/imx53-qsb.dts |8 +- arch/arm/boot/dts/imx6dl.dtsi |5 + arch/arm/boot/dts/imx6q.dtsi|5 + arch/arm/boot/dts/imx6qdl-sabresd.dtsi |6 + arch/arm/boot/dts/imx6qdl.dtsi |9 + drivers/base/Makefile |2 +- drivers/base/component.c| 379 ++ drivers/gpu/drm/drm_crtc_helper.c | 39 +- drivers/staging/imx-drm/Kconfig |6 + drivers/staging/imx-drm/Makefile|5 +- drivers/staging/imx-drm/dw-hdmi-audio.c | 550 drivers/staging/imx-drm/dw-hdmi-audio.h | 13 + drivers/staging/imx-drm/imx-drm-core.c | 827 - drivers/staging/imx-drm/imx-drm.h | 38 +- drivers/staging/imx-drm/imx-fb.c| 47 - drivers/staging/imx-drm/imx-fbdev.c | 74 -- drivers/staging/imx-drm/imx-hdmi.c | 1796 +++ drivers/staging/imx-drm/imx-hdmi.h | 1037 drivers/staging/imx-drm/imx-ldb.c | 125 +-- drivers/staging/imx-drm/imx-tve.c | 134 +- drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h |1 + drivers/staging/imx-drm/ipu-v3/ipu-common.c | 15 +- drivers/staging/imx-drm/ipu-v3/ipu-di.c | 317 ++--- drivers/staging/imx-drm/ipuv3-crtc.c| 59 +- drivers/staging/imx-drm/parallel-display.c | 100 +- include/drm/drm_crtc_helper.h |1 + include/linux/component.h | 31 + include/linux/mfd/syscon/imx6q-iomuxc-gpr.h |1 + 31 files changed, 4519 insertions(+), 1135 deletions(-) create mode 100644 drivers/base/component.c create mode 100644 drivers/staging/imx-drm/dw-hdmi-audio.c create mode 100644 drivers/staging/imx-drm/dw-hdmi-audio.h delete mode 100644 drivers/staging/imx-drm/imx-fb.c delete mode 100644 drivers/staging/imx-drm/imx-fbdev.c create mode 100644 drivers/staging/imx-drm/imx-hdmi.c create mode 100644 drivers/staging/imx-drm/imx-hdmi.h create mode 100644 include/linux/component.h -- FTTC broadband for 0.8mile line: 5.8Mbps down 500kbps up. Estimation in database were 13.1 to 19Mbit for a good line, about 7.5+ for a bad. Estimate before purchase was "up to 13.2Mbit". ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 32/46] imx-drm: use supplied drm_device where possible
The component helper provides us the drm_device which is being registered. Rather than having to reference a global in imx-drm-core, use this to get the imxdrm device, and also use it to register the CRTC against. This means we never have CRTCs/encoders/connectors without the drivers private data being accessible. Remove the module owner field as well; this provides no protection against the device being unbound. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 34 --- drivers/staging/imx-drm/imx-drm.h |4 +- drivers/staging/imx-drm/ipuv3-crtc.c |9 --- 3 files changed, 12 insertions(+), 35 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 08e7837d6134..b11568d6444b 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -52,7 +52,6 @@ struct imx_drm_crtc { struct imx_drm_device *imxdrm; int pipe; struct imx_drm_crtc_helper_funcsimx_drm_helper_funcs; - struct module *owner; struct crtc_cookie cookie; int mux_id; }; @@ -74,7 +73,6 @@ static int legacyfb_depth = 16; module_param(legacyfb_depth, int, 0444); static void imx_drm_device_put(void); -static struct imx_drm_device *__imx_drm_device(void); int imx_drm_crtc_id(struct imx_drm_crtc *crtc) { @@ -114,7 +112,7 @@ static int imx_drm_driver_unload(struct drm_device *drm) struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) { - struct imx_drm_device *imxdrm = __imx_drm_device(); + struct imx_drm_device *imxdrm = crtc->dev->dev_private; unsigned i; for (i = 0; i < MAX_CRTC; i++) @@ -241,7 +239,6 @@ static struct drm_device *imx_drm_device_get(void) struct imx_drm_device *imxdrm = __imx_drm_device(); struct imx_drm_encoder *enc; struct imx_drm_connector *con; - struct imx_drm_crtc *crtc; list_for_each_entry(enc, &imxdrm->encoder_list, list) { if (!try_module_get(enc->owner)) { @@ -259,19 +256,8 @@ static struct drm_device *imx_drm_device_get(void) } } - list_for_each_entry(crtc, &imxdrm->crtc_list, list) { - if (!try_module_get(crtc->owner)) { - dev_err(imxdrm->dev, "could not get module %s\n", - module_name(crtc->owner)); - goto unwind_crtc; - } - } - return imxdrm->drm; -unwind_crtc: - list_for_each_entry_continue_reverse(crtc, &imxdrm->crtc_list, list) - module_put(crtc->owner); unwind_con: list_for_each_entry_continue_reverse(con, &imxdrm->connector_list, list) module_put(con->owner); @@ -290,13 +276,9 @@ static void imx_drm_device_put(void) struct imx_drm_device *imxdrm = __imx_drm_device(); struct imx_drm_encoder *enc; struct imx_drm_connector *con; - struct imx_drm_crtc *crtc; mutex_lock(&imxdrm->mutex); - list_for_each_entry(crtc, &imxdrm->crtc_list, list) - module_put(crtc->owner); - list_for_each_entry(con, &imxdrm->connector_list, list) module_put(con->owner); @@ -535,12 +517,12 @@ static void imx_drm_update_possible_crtcs(void) * The return value if !NULL is a cookie for the caller to pass to * imx_drm_remove_crtc later. */ -int imx_drm_add_crtc(struct drm_crtc *crtc, +int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, struct imx_drm_crtc **new_crtc, const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs, - struct module *owner, void *cookie, int id) + void *cookie, int id) { - struct imx_drm_device *imxdrm = __imx_drm_device(); + struct imx_drm_device *imxdrm = drm->dev_private; struct imx_drm_crtc *imx_drm_crtc; int ret; @@ -574,8 +556,6 @@ int imx_drm_add_crtc(struct drm_crtc *crtc, imx_drm_crtc->crtc = crtc; imx_drm_crtc->imxdrm = imxdrm; - imx_drm_crtc->owner = owner; - imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc; *new_crtc = imx_drm_crtc; @@ -587,11 +567,9 @@ int imx_drm_add_crtc(struct drm_crtc *crtc, drm_crtc_helper_add(crtc, imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs); - drm_crtc_init(imxdrm->drm, crtc, + drm_crtc_init(drm, crtc, imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs); - drm_mode_group_reinit(imxdrm->drm); - imx_drm_update_possible_crtcs(); mutex_unlock(&imxdrm->mutex); @@ -621,8 +599,6 @@ int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc) imxdrm->crtc[imx_drm_crtc->pipe] = NULL; -
[PATCH RFC 09/46] imx-drm: update and fix imx6 DT descriptions for v3 HDMI driver
Signed-off-by: Russell King --- arch/arm/boot/dts/imx6dl.dtsi |3 ++- arch/arm/boot/dts/imx6q.dtsi |1 + arch/arm/boot/dts/imx6qdl.dtsi |1 - 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi index 65e54b4529c5..6dc397022214 100644 --- a/arch/arm/boot/dts/imx6dl.dtsi +++ b/arch/arm/boot/dts/imx6dl.dtsi @@ -90,5 +90,6 @@ }; &hdmi { + compatible = "fsl,imx6dl-hdmi"; crtcs = <&ipu1 0>, <&ipu1 1>; -} +}; diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index d2467f532de6..187fe33ba515 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -161,5 +161,6 @@ }; &hdmi { + compatible = "fsl,imx6q-hdmi"; crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; }; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index 400bbc624f25..930ebe0c2937 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -1369,7 +1369,6 @@ }; hdmi: hdmi@012 { - compatible = "fsl,imx6q-hdmi"; reg = <0x0012 0x9000>; interrupts = <0 115 0x04>; gpr = <&gpr>; -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 10/46] imx-drm: imx-hdmi: fix PLL lock wait
Enabling the debug for PLL lock shows that this times out almost every time. Having such an event at debug level is probably a bug in itself because it hides this fact. Waiting 5ms seems to allow it to lock. Also, adjust the loop so that we check for success before checking whether we've timed out: we don't want to wait and then fail without first checking whether we locked. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c | 20 1 files changed, 12 insertions(+), 8 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 2022635fffdf..ff00759b4d6f 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1032,16 +1032,20 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep, imx_hdmi_phy_gen2_pddq(hdmi, 0); /*Wait for PHY PLL lock */ - msec = 4; - val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; - while (!val) { - udelay(1000); - if (msec-- == 0) { - dev_dbg(hdmi->dev, "PHY PLL not locked\n"); + msec = 5; + do { + val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; + if (!val) + break; + + if (msec == 0) { + dev_err(hdmi->dev, "PHY PLL not locked\n"); return -EINVAL; } - val = hdmi_readb(hdmi, HDMI_PHY_STAT0) & HDMI_PHY_TX_PHY_LOCK; - } + + udelay(1000); + msec--; + } while (1); return 0; } -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 08/46] imx-drm: add imx6 DT configuration for HDMI
Extracted from another patch by Fabio Estevam, this adds the DT configuration for HDMI output on the IMX6 SoCs Signed-off-by: Russell King --- arch/arm/boot/dts/imx6dl.dtsi |4 arch/arm/boot/dts/imx6q.dtsi |4 arch/arm/boot/dts/imx6qdl.dtsi | 10 ++ 3 files changed, 18 insertions(+), 0 deletions(-) diff --git a/arch/arm/boot/dts/imx6dl.dtsi b/arch/arm/boot/dts/imx6dl.dtsi index 9e8ae118fdd4..65e54b4529c5 100644 --- a/arch/arm/boot/dts/imx6dl.dtsi +++ b/arch/arm/boot/dts/imx6dl.dtsi @@ -88,3 +88,7 @@ crtcs = <&ipu1 0>, <&ipu1 1>; }; }; + +&hdmi { + crtcs = <&ipu1 0>, <&ipu1 1>; +} diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index f024ef28b34b..d2467f532de6 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi @@ -159,3 +159,7 @@ crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; }; }; + +&hdmi { + crtcs = <&ipu1 0>, <&ipu1 1>, <&ipu2 0>, <&ipu2 1>; +}; diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi index fb28b2ecb1db..400bbc624f25 100644 --- a/arch/arm/boot/dts/imx6qdl.dtsi +++ b/arch/arm/boot/dts/imx6qdl.dtsi @@ -1368,6 +1368,16 @@ }; }; + hdmi: hdmi@012 { + compatible = "fsl,imx6q-hdmi"; + reg = <0x0012 0x9000>; + interrupts = <0 115 0x04>; + gpr = <&gpr>; + clocks = <&clks 123>, <&clks 124>; + clock-names = "iahb", "isfr"; + status = "disabled"; + }; + dcic1: dcic@020e4000 { reg = <0x020e4000 0x4000>; interrupts = <0 124 0x04>; -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 34/46] imx-drm: imx-drm-core: provide common connector and encoder cleanup functions
Provide two helper functions to assist with cleaning up imx-drm connectors and encoders. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 13 + drivers/staging/imx-drm/imx-drm.h |2 ++ 2 files changed, 15 insertions(+), 0 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 1cfb8a18d905..30d516cc76bb 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -363,6 +363,19 @@ static void imx_drm_connector_unregister( drm_mode_group_reinit(imxdrm->drm); } +void imx_drm_connector_destroy(struct drm_connector *connector) +{ + drm_sysfs_connector_remove(connector); + drm_connector_cleanup(connector); +} +EXPORT_SYMBOL_GPL(imx_drm_connector_destroy); + +void imx_drm_encoder_destroy(struct drm_encoder *encoder) +{ + drm_encoder_cleanup(encoder); +} +EXPORT_SYMBOL_GPL(imx_drm_encoder_destroy); + static struct drm_mode_config_funcs imx_drm_mode_config_funcs = { .fb_create = drm_fb_cma_create, }; diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index 49d4aaf33f97..d13d518e8eb9 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -69,5 +69,7 @@ int imx_drm_encoder_parse_of(struct drm_device *drm, int imx_drm_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode); +void imx_drm_connector_destroy(struct drm_connector *connector); +void imx_drm_encoder_destroy(struct drm_encoder *encoder); #endif /* _IMX_DRM_H_ */ -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 31/46] imx-drm: remove imx-fb.c
imx-fb.c doesn't need to be separate from imx-drm-core.c - all it is doing is setting up the minimum and maximum sizes of the scanout buffers, and setting up the mode_config function pointers. Move the contents into imx-drm-core.c and kill this file. Signed-off-by: Russell King --- drivers/staging/imx-drm/Makefile |2 +- drivers/staging/imx-drm/imx-drm-core.c | 16 ++- drivers/staging/imx-drm/imx-fb.c | 47 3 files changed, 16 insertions(+), 49 deletions(-) delete mode 100644 drivers/staging/imx-drm/imx-fb.c diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index 5239f908ceec..129e3a3f59f1 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -1,5 +1,5 @@ -imxdrm-objs := imx-drm-core.o imx-fb.o +imxdrm-objs := imx-drm-core.o obj-$(CONFIG_DRM_IMX) += imxdrm.o diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 31bc8d9c49be..08e7837d6134 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -381,6 +381,10 @@ static void imx_drm_connector_unregister( drm_mode_group_reinit(imxdrm->drm); } +static struct drm_mode_config_funcs imx_drm_mode_config_funcs = { + .fb_create = drm_fb_cma_create, +}; + /* * Main DRM initialisation. This binds, initialises and registers * with DRM the subcomponents of the driver. @@ -406,8 +410,18 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) */ drm->irq_enabled = true; + /* +* set max width and height as default value(4096x4096). +* this value would be used to check framebuffer size limitation +* at drm_mode_addfb(). +*/ + drm->mode_config.min_width = 64; + drm->mode_config.min_height = 64; + drm->mode_config.max_width = 4096; + drm->mode_config.max_height = 4096; + drm->mode_config.funcs = &imx_drm_mode_config_funcs; + drm_mode_config_init(drm); - imx_drm_mode_config_init(drm); mutex_lock(&imxdrm->mutex); diff --git a/drivers/staging/imx-drm/imx-fb.c b/drivers/staging/imx-drm/imx-fb.c deleted file mode 100644 index 03a7b4e14f67.. --- a/drivers/staging/imx-drm/imx-fb.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * i.MX drm driver - * - * Copyright (C) 2012 Sascha Hauer, Pengutronix - * - * Based on Samsung Exynos code - * - * Copyright (c) 2011 Samsung Electronics Co., Ltd. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - */ -#include -#include -#include -#include -#include -#include - -#include "imx-drm.h" - -static struct drm_mode_config_funcs imx_drm_mode_config_funcs = { - .fb_create = drm_fb_cma_create, -}; - -void imx_drm_mode_config_init(struct drm_device *dev) -{ - dev->mode_config.min_width = 64; - dev->mode_config.min_height = 64; - - /* -* set max width and height as default value(4096x4096). -* this value would be used to check framebuffer size limitation -* at drm_mode_addfb(). -*/ - dev->mode_config.max_width = 4096; - dev->mode_config.max_height = 4096; - - dev->mode_config.funcs = &imx_drm_mode_config_funcs; -} -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 05/46] imx-drm: ipu-v3: don't use clk_round_rate() before clk_set_rate()
This is nonsense; clk_round_rate() is just clk_set_rate() without the side effect of changing the hardware. Signed-off-by: Russell King --- drivers/staging/imx-drm/ipu-v3/ipu-di.c | 13 + 1 files changed, 9 insertions(+), 4 deletions(-) diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-di.c b/drivers/staging/imx-drm/ipu-v3/ipu-di.c index 8c7241bb435c..d766e18bfca0 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-di.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-di.c @@ -560,9 +560,10 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig) * rate within 1% of the requested frequency, otherwise we use * the DI clock. */ - if (sig->clkflags & IPU_DI_CLKMODE_EXT) + round = sig->pixelclock; + if (sig->clkflags & IPU_DI_CLKMODE_EXT) { parent = di->clk_di; - else { + } else { unsigned long rate, clkrate; unsigned div, error; @@ -584,6 +585,9 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig) ret = clk_set_rate(parent, sig->pixelclock); if (ret) dev_err(di->ipu->dev, "Setting of DI clock failed: %d\n", ret); + + /* Use the integer divisor rate - avoid fractional dividers */ + round = rate; } } @@ -599,11 +603,12 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig) * CLKMODE_SYNC means that we want the DI to be clocked at the * same rate as the parent clock. This is needed (eg) for LDB * which needs to be fed with the same pixel clock. +* +* Note: clk_set_rate(clk, clk_round_rate(clk, rate)) is the +* same as clk_set_rate(clk, rate); */ if (sig->clkflags & IPU_DI_CLKMODE_SYNC) round = clk_get_rate(parent); - else - round = clk_round_rate(di->clk_di_pixel, sig->pixelclock); ret = clk_set_rate(di->clk_di_pixel, round); -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 02/46] imx-drm: imx-drm-core: avoid going the long route round for drm_device
We have the drm_device available, so rather than storing it and then using the stored version, us the one we already have available to us. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 16 1 files changed, 8 insertions(+), 8 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 9aa5eaab6539..242e8db218ac 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -88,9 +88,9 @@ static int imx_drm_driver_unload(struct drm_device *drm) imx_drm_device_put(); - drm_vblank_cleanup(imxdrm->drm); - drm_kms_helper_poll_fini(imxdrm->drm); - drm_mode_config_cleanup(imxdrm->drm); + drm_vblank_cleanup(drm); + drm_kms_helper_poll_fini(drm); + drm_mode_config_cleanup(drm); return 0; } @@ -424,15 +424,15 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) mutex_lock(&imxdrm->mutex); - drm_kms_helper_poll_init(imxdrm->drm); + drm_kms_helper_poll_init(drm); /* setup the grouping for the legacy output */ - ret = drm_mode_group_init_legacy_group(imxdrm->drm, - &imxdrm->drm->primary->mode_group); + ret = drm_mode_group_init_legacy_group(drm, + &drm->primary->mode_group); if (ret) goto err_kms; - ret = drm_vblank_init(imxdrm->drm, MAX_CRTC); + ret = drm_vblank_init(drm, MAX_CRTC); if (ret) goto err_kms; @@ -441,7 +441,7 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) * by drm timer once a current process gives up ownership of * vblank event.(after drm_vblank_put function is called) */ - imxdrm->drm->vblank_disable_allowed = true; + drm->vblank_disable_allowed = true; if (!imx_drm_device_get()) { ret = -EINVAL; -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 30/46] imx-drm: remove separate imx-fbdev
Now that we know when the components of the imx-drm subsystem will be initialised, we can move the fbdev helper initialisation and teardown into imx-drm-core. This gives us the required ordering that DRM wants in both driver load and unload methods. We can also stop exporting the imx_drm_device_get() and imx_drm_device_put() methods; nothing but the fbdev helper was making use of these. Signed-off-by: Russell King --- drivers/staging/imx-drm/Makefile |1 - drivers/staging/imx-drm/imx-drm-core.c | 43 +- drivers/staging/imx-drm/imx-drm.h |3 - drivers/staging/imx-drm/imx-fbdev.c| 74 4 files changed, 31 insertions(+), 90 deletions(-) delete mode 100644 drivers/staging/imx-drm/imx-fbdev.c diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index 4677585b5ad5..5239f908ceec 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -6,7 +6,6 @@ obj-$(CONFIG_DRM_IMX) += imxdrm.o obj-$(CONFIG_DRM_IMX_PARALLEL_DISPLAY) += parallel-display.o obj-$(CONFIG_DRM_IMX_TVE) += imx-tve.o obj-$(CONFIG_DRM_IMX_LDB) += imx-ldb.o -obj-$(CONFIG_DRM_IMX_FB_HELPER) += imx-fbdev.o obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/ imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index d5bf4a4646a3..31bc8d9c49be 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -70,6 +70,10 @@ struct imx_drm_connector { struct module *owner; }; +static int legacyfb_depth = 16; +module_param(legacyfb_depth, int, 0444); + +static void imx_drm_device_put(void); static struct imx_drm_device *__imx_drm_device(void); int imx_drm_crtc_id(struct imx_drm_crtc *crtc) @@ -82,14 +86,21 @@ static void imx_drm_driver_lastclose(struct drm_device *drm) { struct imx_drm_device *imxdrm = drm->dev_private; +#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER) if (imxdrm->fbhelper) drm_fbdev_cma_restore_mode(imxdrm->fbhelper); +#endif } static int imx_drm_driver_unload(struct drm_device *drm) { struct imx_drm_device *imxdrm = drm->dev_private; +#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER) + if (imxdrm->fbhelper) + drm_fbdev_cma_fini(imxdrm->fbhelper); +#endif + component_unbind_all(drm->dev, drm); imx_drm_device_put(); @@ -225,7 +236,7 @@ static struct imx_drm_device *__imx_drm_device(void) return imx_drm_device; } -struct drm_device *imx_drm_device_get(void) +static struct drm_device *imx_drm_device_get(void) { struct imx_drm_device *imxdrm = __imx_drm_device(); struct imx_drm_encoder *enc; @@ -273,9 +284,8 @@ struct drm_device *imx_drm_device_get(void) return NULL; } -EXPORT_SYMBOL_GPL(imx_drm_device_get); -void imx_drm_device_put(void) +static void imx_drm_device_put(void) { struct imx_drm_device *imxdrm = __imx_drm_device(); struct imx_drm_encoder *enc; @@ -295,7 +305,6 @@ void imx_drm_device_put(void) mutex_unlock(&imxdrm->mutex); } -EXPORT_SYMBOL_GPL(imx_drm_device_put); static int drm_mode_group_reinit(struct drm_device *dev) { @@ -449,6 +458,24 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) } } + /* +* All components are now initialised, so setup the fb helper. +* The fb helper takes copies of key hardware information, so the +* crtcs/connectors/encoders must not change after this point. +*/ +#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER) + if (legacyfb_depth != 16 && legacyfb_depth != 32) { + dev_warn(drm->dev, "Invalid legacyfb_depth. Defaulting to 16bpp\n"); + legacyfb_depth = 16; + } + imxdrm->fbhelper = drm_fbdev_cma_init(drm, legacyfb_depth, + drm->mode_config.num_crtc, 4); + if (IS_ERR(imxdrm->fbhelper)) { + ret = PTR_ERR(imxdrm->fbhelper); + imxdrm->fbhelper = NULL; + goto err_unbind; + } +#endif return 0; err_unbind: @@ -766,14 +793,6 @@ int imx_drm_add_connector(struct drm_connector *connector, } EXPORT_SYMBOL_GPL(imx_drm_add_connector); -void imx_drm_fb_helper_set(struct drm_fbdev_cma *fbdev_helper) -{ - struct imx_drm_device *imxdrm = __imx_drm_device(); - - imxdrm->fbhelper = fbdev_helper; -} -EXPORT_SYMBOL_GPL(imx_drm_fb_helper_set); - /* * imx_drm_remove_connector - remove a connector */ diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index e3ca0c6b6a39..d1fb1146240e 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -54,13 +54,10 @@ void imx_drm_mode_config_init(struct drm_device *drm); struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffe
[PATCH RFC 03/46] imx-drm: imx-drm-core: merge imx_drm_crtc_register() into imx_drm_add_crtc()
There's no reason for this to be a separate function; merge the two together. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 33 --- 1 files changed, 9 insertions(+), 24 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 242e8db218ac..05dd24ee80dd 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -370,29 +370,6 @@ static void imx_drm_connector_unregister( } /* - * register a crtc to the drm core - */ -static int imx_drm_crtc_register(struct imx_drm_crtc *imx_drm_crtc) -{ - struct imx_drm_device *imxdrm = __imx_drm_device(); - int ret; - - ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256); - if (ret) - return ret; - - drm_crtc_helper_add(imx_drm_crtc->crtc, - imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs); - - drm_crtc_init(imxdrm->drm, imx_drm_crtc->crtc, - imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs); - - drm_mode_group_reinit(imxdrm->drm); - - return 0; -} - -/* * Called by the CRTC driver when all CRTCs are registered. This * puts all the pieces together and initializes the driver. * Once this is called no more CRTCs can be registered since @@ -535,10 +512,18 @@ int imx_drm_add_crtc(struct drm_crtc *crtc, *new_crtc = imx_drm_crtc; - ret = imx_drm_crtc_register(imx_drm_crtc); + ret = drm_mode_crtc_set_gamma_size(imx_drm_crtc->crtc, 256); if (ret) goto err_register; + drm_crtc_helper_add(crtc, + imx_drm_crtc->imx_drm_helper_funcs.crtc_helper_funcs); + + drm_crtc_init(imxdrm->drm, crtc, + imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs); + + drm_mode_group_reinit(imxdrm->drm); + imx_drm_update_possible_crtcs(); mutex_unlock(&imxdrm->mutex); -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 04/46] imx-drm: ipu-v3: more inteligent DI clock selection
The DI clock selection was very rudimentary: it would statically use either the IPU internal clock or the DI external clock depending on which "encoder" was being used. In the case of HDMI, it would always use the IPU clock. Moreover, using the IPU clock resulted in fractional divisors, which are achieved by skipping clock pulses. This can result in the HDMI PHY PLL being frequency modulated, and the attached device is then unable to properly lock on to the TMDS clock. We need at least 1% accurate and stable clocks for HDMI. Arrange for the DI clock to be sourced from the IPU internal clock if it can satisfy our requirements, otherwise switch to the DI external clock and try and set the external clock to our desired pixel clock rate. Signed-off-by: Russell King --- drivers/staging/imx-drm/ipu-v3/ipu-di.c | 54 +- 1 files changed, 52 insertions(+), 2 deletions(-) diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-di.c b/drivers/staging/imx-drm/ipu-v3/ipu-di.c index 948a49b289ef..8c7241bb435c 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-di.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-di.c @@ -544,10 +544,48 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig) if ((sig->v_sync_width == 0) || (sig->h_sync_width == 0)) return -EINVAL; + dev_dbg(di->ipu->dev, "Clocks: IPU %luHz DI %luHz Needed %luHz\n", + clk_get_rate(di->clk_ipu), + clk_get_rate(di->clk_di), + sig->pixelclock); + + /* +* CLKMODE_EXT means we must use the DI clock: this is needed +* for things like LVDS which needs to feed the DI and LDB with +* the same pixel clock. +* +* For other interfaces, we can arbitarily select between the DI +* specific clock and the internal IPU clock. See DI_GENERAL +* bit 20. We select the IPU clock if it can give us a clock +* rate within 1% of the requested frequency, otherwise we use +* the DI clock. +*/ if (sig->clkflags & IPU_DI_CLKMODE_EXT) parent = di->clk_di; - else - parent = di->clk_ipu; + else { + unsigned long rate, clkrate; + unsigned div, error; + + clkrate = clk_get_rate(di->clk_ipu); + div = (clkrate + sig->pixelclock / 2) / sig->pixelclock; + rate = clkrate / div; + + error = rate / (sig->pixelclock / 1000); + + dev_dbg(di->ipu->dev, " IPU clock can give %lu with divider %u, error %d.%u%%\n", + rate, div, (signed)(error - 1000) / 10, error % 10); + + /* Allow a 1% error */ + if (error < 1010 && error >= 990) { + parent = di->clk_ipu; + } else { + parent = di->clk_di; + + ret = clk_set_rate(parent, sig->pixelclock); + if (ret) + dev_err(di->ipu->dev, "Setting of DI clock failed: %d\n", ret); + } + } ret = clk_set_parent(di->clk_di_pixel, parent); if (ret) { @@ -557,6 +595,11 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig) return ret; } + /* +* CLKMODE_SYNC means that we want the DI to be clocked at the +* same rate as the parent clock. This is needed (eg) for LDB +* which needs to be fed with the same pixel clock. +*/ if (sig->clkflags & IPU_DI_CLKMODE_SYNC) round = clk_get_rate(parent); else @@ -564,6 +607,13 @@ int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig) ret = clk_set_rate(di->clk_di_pixel, round); + dev_dbg(di->ipu->dev, "Want %luHz IPU %luHz DI %luHz using %s, got %luHz\n", + sig->pixelclock, + clk_get_rate(di->clk_ipu), + clk_get_rate(di->clk_di), + parent == di->clk_di ? "DI" : "IPU", + clk_get_rate(di->clk_di_pixel)); + h_total = sig->width + sig->h_sync_width + sig->h_start_width + sig->h_end_width; v_total = sig->height + sig->v_sync_width + sig->v_start_width + -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 06/46] imx-drm: ipu-v3: more clocking fixes
There's no point in using the clk API for this; we end up having to violate the layering this provides. Signed-off-by: Russell King --- drivers/staging/imx-drm/ipu-v3/ipu-di.c | 328 ++- 1 files changed, 105 insertions(+), 223 deletions(-) diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-di.c b/drivers/staging/imx-drm/ipu-v3/ipu-di.c index d766e18bfca0..82a9ebad697c 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-di.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-di.c @@ -19,9 +19,6 @@ #include #include #include -#include -#include -#include #include "imx-ipu-v3.h" #include "ipu-prv.h" @@ -33,10 +30,7 @@ struct ipu_di { struct clk *clk_di; /* display input clock */ struct clk *clk_ipu;/* IPU bus clock */ struct clk *clk_di_pixel; /* resulting pixel clock */ - struct clk_hw clk_hw_out; - char *clk_name; bool inuse; - unsigned long clkflags; struct ipu_soc *ipu; }; @@ -141,130 +135,6 @@ static inline void ipu_di_write(struct ipu_di *di, u32 value, unsigned offset) writel(value, di->base + offset); } -static int ipu_di_clk_calc_div(unsigned long inrate, unsigned long outrate) -{ - u64 tmp = inrate; - int div; - - tmp *= 16; - - do_div(tmp, outrate); - - div = tmp; - - if (div < 0x10) - div = 0x10; - -#ifdef WTF_IS_THIS - /* -* Freescale has this in their Kernel. It is neither clear what -* it does nor why it does it -*/ - if (div & 0x10) - div &= ~0x7; - else { - /* Round up divider if it gets us closer to desired pix clk */ - if ((div & 0xC) == 0xC) { - div += 0x10; - div &= ~0xF; - } - } -#endif - return div; -} - -static unsigned long clk_di_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out); - unsigned long outrate; - u32 div = ipu_di_read(di, DI_BS_CLKGEN0); - - if (div < 0x10) - div = 0x10; - - outrate = (parent_rate / div) * 16; - - return outrate; -} - -static long clk_di_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out); - unsigned long outrate; - int div; - u32 val; - - div = ipu_di_clk_calc_div(*prate, rate); - - outrate = (*prate / div) * 16; - - val = ipu_di_read(di, DI_GENERAL); - - if (!(val & DI_GEN_DI_CLK_EXT) && outrate > *prate / 2) - outrate = *prate / 2; - - dev_dbg(di->ipu->dev, - "%s: inrate: %ld div: 0x%08x outrate: %ld wanted: %ld\n", - __func__, *prate, div, outrate, rate); - - return outrate; -} - -static int clk_di_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out); - int div; - u32 clkgen0; - - clkgen0 = ipu_di_read(di, DI_BS_CLKGEN0) & ~0xfff; - - div = ipu_di_clk_calc_div(parent_rate, rate); - - ipu_di_write(di, clkgen0 | div, DI_BS_CLKGEN0); - - dev_dbg(di->ipu->dev, "%s: inrate: %ld desired: %ld div: 0x%08x\n", - __func__, parent_rate, rate, div); - return 0; -} - -static u8 clk_di_get_parent(struct clk_hw *hw) -{ - struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out); - u32 val; - - val = ipu_di_read(di, DI_GENERAL); - - return val & DI_GEN_DI_CLK_EXT ? 1 : 0; -} - -static int clk_di_set_parent(struct clk_hw *hw, u8 index) -{ - struct ipu_di *di = container_of(hw, struct ipu_di, clk_hw_out); - u32 val; - - val = ipu_di_read(di, DI_GENERAL); - - if (index) - val |= DI_GEN_DI_CLK_EXT; - else - val &= ~DI_GEN_DI_CLK_EXT; - - ipu_di_write(di, val, DI_GENERAL); - - return 0; -} - -static struct clk_ops clk_di_ops = { - .round_rate = clk_di_round_rate, - .set_rate = clk_di_set_rate, - .recalc_rate = clk_di_recalc_rate, - .set_parent = clk_di_set_parent, - .get_parent = clk_di_get_parent, -}; - static void ipu_di_data_wave_config(struct ipu_di *di, int wave_gen, int access_size, int component_size) @@ -528,42 +398,58 @@ static void ipu_di_sync_config_noninterlaced(struct ipu_di *di, ipu_di_sync_config(di, cfg_vga, 0, ARRAY_SIZE(cfg_vga)); } -int ipu_di_init_sync_panel(struct ipu_di *di, struct ipu_di_signal_cfg *sig) +static void ipu_di_config_clock(struct ipu_di *di, + const struct ipu_di_signal_cfg *sig) { - u32 reg; - u32 di_gen, vsync_cnt; - u32 div;
[PATCH RFC 35/46] imx-drm: parallel-display,imx-tve,imx-ldb: initialise drm components directly
Now that our bind function is only ever called during the main DRM driver ->load callback, we don't need to have the imx_drm_connector or imx_drm_encoder abstractions anymore. So let's get rid of it, and move the DRM connector and encoder setup into the connector support files. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-ldb.c | 68 +--- drivers/staging/imx-drm/imx-tve.c | 58 ++- drivers/staging/imx-drm/parallel-display.c | 61 +++-- 3 files changed, 54 insertions(+), 133 deletions(-) diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 5b71f49faa0a..601f9c5c5340 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -59,9 +59,8 @@ struct imx_ldb; struct imx_ldb_channel { struct imx_ldb *ldb; struct drm_connector connector; - struct imx_drm_connector *imx_drm_connector; struct drm_encoder encoder; - struct imx_drm_encoder *imx_drm_encoder; + struct device_node *child; int chno; void *edid; int edid_len; @@ -92,11 +91,6 @@ static enum drm_connector_status imx_ldb_connector_detect( return connector_status_connected; } -static void imx_ldb_connector_destroy(struct drm_connector *connector) -{ - /* do not free here */ -} - static int imx_ldb_connector_get_modes(struct drm_connector *connector) { struct imx_ldb_channel *imx_ldb_ch = con_to_imx_ldb_ch(connector); @@ -309,16 +303,11 @@ static void imx_ldb_encoder_disable(struct drm_encoder *encoder) } } -static void imx_ldb_encoder_destroy(struct drm_encoder *encoder) -{ - /* do not free here */ -} - static struct drm_connector_funcs imx_ldb_connector_funcs = { .dpms = drm_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = imx_ldb_connector_detect, - .destroy = imx_ldb_connector_destroy, + .destroy = imx_drm_connector_destroy, }; static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = { @@ -328,7 +317,7 @@ static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = { }; static struct drm_encoder_funcs imx_ldb_encoder_funcs = { - .destroy = imx_ldb_encoder_destroy, + .destroy = imx_drm_encoder_destroy, }; static struct drm_encoder_helper_funcs imx_ldb_encoder_helper_funcs = { @@ -355,45 +344,36 @@ static int imx_ldb_get_clk(struct imx_ldb *ldb, int chno) return PTR_ERR_OR_ZERO(ldb->clk_pll[chno]); } -static int imx_ldb_register(struct imx_ldb_channel *imx_ldb_ch) +static int imx_ldb_register(struct drm_device *drm, + struct imx_ldb_channel *imx_ldb_ch) { - int ret; struct imx_ldb *ldb = imx_ldb_ch->ldb; + int ret; + + ret = imx_drm_encoder_parse_of(drm, &imx_ldb_ch->encoder, + imx_ldb_ch->child); + if (ret) + return ret; ret = imx_ldb_get_clk(ldb, imx_ldb_ch->chno); if (ret) return ret; + if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) { - ret |= imx_ldb_get_clk(ldb, 1); + ret = imx_ldb_get_clk(ldb, 1); if (ret) return ret; } - imx_ldb_ch->connector.funcs = &imx_ldb_connector_funcs; - imx_ldb_ch->encoder.funcs = &imx_ldb_encoder_funcs; - - imx_ldb_ch->encoder.encoder_type = DRM_MODE_ENCODER_LVDS; - imx_ldb_ch->connector.connector_type = DRM_MODE_CONNECTOR_LVDS; - drm_encoder_helper_add(&imx_ldb_ch->encoder, &imx_ldb_encoder_helper_funcs); - ret = imx_drm_add_encoder(&imx_ldb_ch->encoder, - &imx_ldb_ch->imx_drm_encoder, THIS_MODULE); - if (ret) { - dev_err(ldb->dev, "adding encoder failed with %d\n", ret); - return ret; - } + drm_encoder_init(drm, &imx_ldb_ch->encoder, &imx_ldb_encoder_funcs, +DRM_MODE_ENCODER_LVDS); drm_connector_helper_add(&imx_ldb_ch->connector, &imx_ldb_connector_helper_funcs); - - ret = imx_drm_add_connector(&imx_ldb_ch->connector, - &imx_ldb_ch->imx_drm_connector, THIS_MODULE); - if (ret) { - imx_drm_remove_encoder(imx_ldb_ch->imx_drm_encoder); - dev_err(ldb->dev, "adding connector failed with %d\n", ret); - return ret; - } + drm_connector_init(drm, &imx_ldb_ch->connector, + &imx_ldb_connector_funcs, DRM_MODE_CONNECTOR_LVDS); drm_mode_connector_attach_encoder(&imx_ldb_ch->connector, &imx_ldb_ch->encoder); @@ -454,6 +434,7 @@ MODULE_DEVICE_TABLE(of, imx_ldb_dt_ids); static int imx_ldb_bind(struct device *dev, struct device *master, void *data) { + struct drm_device *drm = data;
[PATCH RFC 12/46] imx-drm: imx-hdmi: fix wrong comment
The vsync active edge delay is in lines, not pixel clocks. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c |2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index fe3a6779b620..0cba5d4a9966 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1275,7 +1275,7 @@ static void hdmi_av_composer(struct imx_hdmi *hdmi, hdmi_writeb(hdmi, hsync_len >> 8, HDMI_FC_HSYNCINWIDTH1); hdmi_writeb(hdmi, hsync_len, HDMI_FC_HSYNCINWIDTH0); - /* Set up VSYNC active edge delay (in pixel clks) */ + /* Set up VSYNC active edge delay (in lines) */ vsync_len = mode->vsync_end - mode->vsync_start; hdmi_writeb(hdmi, vsync_len, HDMI_FC_VSYNCINWIDTH); } -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 40/46] imx-drm: imx-drm-core: move allocation of imxdrm device to driver load function
It is now no longer necessary to keep this structure around; we can allocate it upon DRM driver load and destroy it thereafter without affecting the other components now. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 47 --- 1 files changed, 6 insertions(+), 41 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 0172739a00fe..8e257c5fb041 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -38,7 +38,6 @@ struct imx_drm_crtc; struct imx_drm_device { struct drm_device *drm; - struct device *dev; struct imx_drm_crtc *crtc[MAX_CRTC]; int pipes; struct drm_fbdev_cma*fbhelper; @@ -206,13 +205,6 @@ int imx_drm_connector_mode_valid(struct drm_connector *connector, } EXPORT_SYMBOL(imx_drm_connector_mode_valid); -static struct imx_drm_device *imx_drm_device; - -static struct imx_drm_device *__imx_drm_device(void) -{ - return imx_drm_device; -} - void imx_drm_connector_destroy(struct drm_connector *connector) { drm_sysfs_connector_remove(connector); @@ -236,10 +228,14 @@ static struct drm_mode_config_funcs imx_drm_mode_config_funcs = { */ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) { - struct imx_drm_device *imxdrm = __imx_drm_device(); + struct imx_drm_device *imxdrm; struct drm_connector *connector; int ret; + imxdrm = devm_kzalloc(drm->dev, sizeof(*imxdrm), GFP_KERNEL); + if (!imxdrm) + return -ENOMEM; + imxdrm->drm = drm; drm->dev_private = imxdrm; @@ -602,8 +598,6 @@ static int imx_drm_platform_probe(struct platform_device *pdev) if (ret) return ret; - imx_drm_device->dev = &pdev->dev; - return component_master_add(&pdev->dev, &imx_drm_ops); } @@ -628,36 +622,7 @@ static struct platform_driver imx_drm_pdrv = { .of_match_table = imx_drm_dt_ids, }, }; - -static int __init imx_drm_init(void) -{ - int ret; - - imx_drm_device = kzalloc(sizeof(*imx_drm_device), GFP_KERNEL); - if (!imx_drm_device) - return -ENOMEM; - - ret = platform_driver_register(&imx_drm_pdrv); - if (ret) - goto err_pdrv; - - return 0; - -err_pdrv: - kfree(imx_drm_device); - - return ret; -} - -static void __exit imx_drm_exit(void) -{ - platform_driver_unregister(&imx_drm_pdrv); - - kfree(imx_drm_device); -} - -module_init(imx_drm_init); -module_exit(imx_drm_exit); +module_platform_driver(imx_drm_pdrv); MODULE_AUTHOR("Sascha Hauer "); MODULE_DESCRIPTION("i.MX drm driver core"); -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 33/46] imx-drm: imx-drm-core: provide helper function to parse possible crtcs
Provide a helper function to parse possible crtcs before the encoder is registered. The crtc mask is derived from the position of the CRTCs registered in the drm_device. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 66 drivers/staging/imx-drm/imx-drm.h |2 + 2 files changed, 68 insertions(+), 0 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index b11568d6444b..1cfb8a18d905 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -657,6 +657,72 @@ int imx_drm_add_encoder(struct drm_encoder *encoder, } EXPORT_SYMBOL_GPL(imx_drm_add_encoder); +/* + * Find the DRM CRTC possible mask for the device node cookie/id. + * + * The encoder possible masks are defined by their position in the + * mode_config crtc_list. This means that CRTCs must not be added + * or removed once the DRM device has been fully initialised. + */ +static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm, + void *cookie, int id) +{ + unsigned i; + + for (i = 0; i < MAX_CRTC; i++) { + struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i]; + if (imx_drm_crtc && imx_drm_crtc->cookie.id == id && + imx_drm_crtc->cookie.cookie == cookie) + return drm_helper_crtc_possible_mask(imx_drm_crtc->crtc); + } + + return 0; +} + +int imx_drm_encoder_parse_of(struct drm_device *drm, + struct drm_encoder *encoder, struct device_node *np) +{ + struct imx_drm_device *imxdrm = drm->dev_private; + uint32_t crtc_mask = 0; + int i, ret = 0; + + for (i = 0; !ret; i++) { + struct of_phandle_args args; + uint32_t mask; + int id; + + ret = of_parse_phandle_with_args(np, "crtcs", "#crtc-cells", i, +&args); + if (ret == -ENOENT) + break; + if (ret < 0) + return ret; + + id = args.args_count > 0 ? args.args[0] : 0; + mask = imx_drm_find_crtc_mask(imxdrm, args.np, id); + of_node_put(args.np); + + /* +* If we failed to find the CRTC(s) which this encoder is +* supposed to be connected to, it's because the CRTC has +* not been registered yet. Defer probing, and hope that +* the required CRTC is added later. +*/ + if (mask == 0) + return -EPROBE_DEFER; + + crtc_mask |= mask; + } + + encoder->possible_crtcs = crtc_mask; + + /* FIXME: this is the mask of outputs which can clone this output. */ + encoder->possible_clones = ~0; + + return 0; +} +EXPORT_SYMBOL_GPL(imx_drm_encoder_parse_of); + int imx_drm_encoder_add_possible_crtcs( struct imx_drm_encoder *imx_drm_encoder, struct device_node *np) diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index 78465239ed4c..49d4aaf33f97 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -64,6 +64,8 @@ struct device_node; int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder); int imx_drm_encoder_add_possible_crtcs(struct imx_drm_encoder *imx_drm_encoder, struct device_node *np); +int imx_drm_encoder_parse_of(struct drm_device *drm, + struct drm_encoder *encoder, struct device_node *np); int imx_drm_connector_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode); -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 11/46] imx-drm: imx-hdmi: fix pixel clock
The correct pixel clock can be found in the drm_display_mode structure. Use this rather than trying to calculate it from the h/v total and the refresh rate, which can be inaccurate. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index ff00759b4d6f..fe3a6779b620 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1206,8 +1206,7 @@ static void hdmi_av_composer(struct imx_hdmi *hdmi, vmode->mhsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PHSYNC); vmode->mvsyncpolarity = !!(mode->flags & DRM_MODE_FLAG_PVSYNC); vmode->minterlaced = !!(mode->flags & DRM_MODE_FLAG_INTERLACE); - vmode->mpixelclock = mode->htotal * mode->vtotal * -drm_mode_vrefresh(mode); + vmode->mpixelclock = mode->clock * 1000; dev_dbg(hdmi->dev, "final pixclk = %d\n", vmode->mpixelclock); -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 20/46] imx-drm: imx-hdmi: fix CTS/N setup at init time
Many of the variables for the audio clock regenerator (CTS/N) were not initialised in any way. The pixel rate which was being used also wasn't being adjusted at all when the display mode is modified. Get rid of the seaprate 'pixel_clk_rate', and use the stored pixel clock rate instead. Pass this desired pixel clock rate into hdmi_set_clk_regenerator(). Collapse down hdmi_init_clk_regenerator() since it is a copy of hdmi_set_clk_regenerator(), and pass a default pixel clock rate. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c | 48 +++ 1 files changed, 10 insertions(+), 38 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 075dd1f0c8a7..2eb51e7ea9bb 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -138,7 +138,6 @@ struct imx_hdmi { struct i2c_adapter *ddc; void __iomem *regs; - unsigned long pixel_clk_rate; unsigned int sample_rate; int ratio; }; @@ -332,34 +331,25 @@ static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk, return (cts * ratio) / 100; } -static void hdmi_get_pixel_clk(struct imx_hdmi *hdmi) -{ - unsigned long rate; - - rate = 6500; /* FIXME */ - - if (rate) - hdmi->pixel_clk_rate = rate; -} - -static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi) +static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi, + unsigned long pixel_clk) { unsigned int clk_n, clk_cts; - clk_n = hdmi_compute_n(hdmi->sample_rate, hdmi->pixel_clk_rate, + clk_n = hdmi_compute_n(hdmi->sample_rate, pixel_clk, hdmi->ratio); - clk_cts = hdmi_compute_cts(hdmi->sample_rate, hdmi->pixel_clk_rate, + clk_cts = hdmi_compute_cts(hdmi->sample_rate, pixel_clk, hdmi->ratio); if (!clk_cts) { dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n", -__func__, hdmi->pixel_clk_rate); +__func__, pixel_clk); return; } dev_dbg(hdmi->dev, "%s: samplerate=%d ratio=%d pixelclk=%lu N=%d cts=%d\n", __func__, hdmi->sample_rate, hdmi->ratio, - hdmi->pixel_clk_rate, clk_n, clk_cts); + pixel_clk, clk_n, clk_cts); hdmi_set_clock_regenerator_n(hdmi, clk_n); hdmi_regenerate_cts(hdmi, clk_cts); @@ -367,32 +357,12 @@ static void hdmi_set_clk_regenerator(struct imx_hdmi *hdmi) static void hdmi_init_clk_regenerator(struct imx_hdmi *hdmi) { - unsigned int clk_n, clk_cts; - - clk_n = hdmi_compute_n(hdmi->sample_rate, hdmi->pixel_clk_rate, - hdmi->ratio); - clk_cts = hdmi_compute_cts(hdmi->sample_rate, hdmi->pixel_clk_rate, - hdmi->ratio); - - if (!clk_cts) { - dev_dbg(hdmi->dev, "%s: pixel clock not supported: %lu\n", -__func__, hdmi->pixel_clk_rate); - return; - } - - dev_dbg(hdmi->dev, "%s: samplerate=%d ratio=%d pixelclk=%lu N=%d cts=%d\n", - __func__, hdmi->sample_rate, hdmi->ratio, - hdmi->pixel_clk_rate, clk_n, clk_cts); - - hdmi_set_clock_regenerator_n(hdmi, clk_n); - hdmi_regenerate_cts(hdmi, clk_cts); + hdmi_set_clk_regenerator(hdmi, 7425); } static void hdmi_clk_regenerator_update_pixel_clock(struct imx_hdmi *hdmi) { - /* Get pixel clock from ipu */ - hdmi_get_pixel_clk(hdmi); - hdmi_set_clk_regenerator(hdmi); + hdmi_set_clk_regenerator(hdmi, hdmi->hdmi_data.video_mode.mpixelclock); } /* @@ -1640,6 +1610,8 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) return -ENOMEM; hdmi->dev = &pdev->dev; + hdmi->sample_rate = 48000; + hdmi->ratio = 100; if (of_id) { const struct platform_device_id *device_id = of_id->data; -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 16/46] imx-drm: imx-hdmi: convert HDMI clock settings to tabular form
Rather than having large if() and switch() statements, provide a table to look up the register settings for various clock rates. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c | 250 ++-- 1 files changed, 95 insertions(+), 155 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index ee0fceb7b5b2..5fda630a798d 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -810,19 +810,94 @@ static void imx_hdmi_phy_sel_interface_control(struct imx_hdmi *hdmi, u8 enable) HDMI_PHY_CONF0_SELDIPIF_MASK); } +enum { + RES_8, + RES_10, + RES_12, + RES_MAX, +}; + +struct mpll_config { + unsigned long mpixelclock; + struct { + u16 cpce; + u16 gmp; + } res[RES_MAX]; +}; + +static const struct mpll_config mpll_config[] = { + { + 4525, { + { 0x01e0, 0x }, + { 0x21e1, 0x }, + { 0x41e2, 0x } + }, + }, { + 9250, { + { 0x0140, 0x0005 }, + { 0x2141, 0x0005 }, + { 0x4142, 0x0005 }, + }, + }, { + 14850, { + { 0x00a0, 0x000a }, + { 0x20a1, 0x000a }, + { 0x40a2, 0x000a }, + }, + }, { + ~0UL, { + { 0x00a0, 0x000a }, + { 0x2001, 0x000f }, + { 0x4002, 0x000f }, + }, + } +}; + +struct curr_ctrl { + unsigned long mpixelclock; + u16 curr[RES_MAX]; +}; + +static const struct curr_ctrl curr_ctrl[] = { + /* pixelclk bpp8bpp10 bpp12 */ + { +5400, { 0x091c, 0x091c, 0x06dc }, + }, { +5840, { 0x091c, 0x06dc, 0x06dc }, + }, { +7200, { 0x06dc, 0x06dc, 0x091c }, + }, { +7425, { 0x06dc, 0x0b5c, 0x091c }, + }, { + 11880, { 0x091c, 0x091c, 0x06dc }, + }, { + 21600, { 0x06dc, 0x0b5c, 0x091c }, + } +}; + static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep, unsigned char res, int cscon) { + unsigned res_idx, i; u8 val, msec; - /* color resolution 0 is 8 bit colour depth */ - if (!res) - res = 8; - if (prep) return -EINVAL; - else if (res != 8 && res != 12) + + switch (res) { + case 0: /* color resolution 0 is 8 bit colour depth */ + case 8: + res_idx = RES_8; + break; + case 10: + res_idx = RES_10; + break; + case 12: + res_idx = RES_12; + break; + default: return -EINVAL; + } /* Enable csc path */ if (cscon) @@ -849,165 +924,30 @@ static int hdmi_phy_configure(struct imx_hdmi *hdmi, unsigned char prep, HDMI_PHY_I2CM_SLAVE_ADDR); hdmi_phy_test_clear(hdmi, 0); - if (hdmi->hdmi_data.video_mode.mpixelclock <= 4525) { - switch (res) { - case 8: - /* PLL/MPLL Cfg */ - hdmi_phy_i2c_write(hdmi, 0x01e0, 0x06); - hdmi_phy_i2c_write(hdmi, 0x, 0x15); /* GMPCTRL */ - break; - case 10: - hdmi_phy_i2c_write(hdmi, 0x21e1, 0x06); - hdmi_phy_i2c_write(hdmi, 0x, 0x15); - break; - case 12: - hdmi_phy_i2c_write(hdmi, 0x41e2, 0x06); - hdmi_phy_i2c_write(hdmi, 0x, 0x15); - break; - default: - return -EINVAL; - } - } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 9250) { - switch (res) { - case 8: - hdmi_phy_i2c_write(hdmi, 0x0140, 0x06); - hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); - break; - case 10: - hdmi_phy_i2c_write(hdmi, 0x2141, 0x06); - hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); - break; - case 12: - hdmi_phy_i2c_write(hdmi, 0x4142, 0x06); - hdmi_phy_i2c_write(hdmi, 0x0005, 0x15); - default: - return -EINVAL; - } - } else if (hdmi->hdmi_data.video_mode.mpixelclock <= 14850) { - switch (res) { - case 8: - hdmi_phy_i2c_write(hdmi
[PATCH RFC 36/46] imx-drm: imx-hdmi: initialise drm components directly
Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c | 56 +-- 1 files changed, 15 insertions(+), 41 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index d81940a8904f..512b39710530 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -117,9 +117,7 @@ struct hdmi_data_info { struct imx_hdmi { struct drm_connector connector; - struct imx_drm_connector *imx_drm_connector; struct drm_encoder encoder; - struct imx_drm_encoder *imx_drm_encoder; enum imx_hdmi_devtype dev_type; struct device *dev; @@ -1382,10 +1380,6 @@ static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector return connector_status_connected; } -static void imx_hdmi_connector_destroy(struct drm_connector *connector) -{ -} - static int imx_hdmi_connector_get_modes(struct drm_connector *connector) { struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi, @@ -1471,13 +1465,8 @@ static void imx_hdmi_encoder_commit(struct drm_encoder *encoder) imx_hdmi_poweron(hdmi); } -static void imx_hdmi_encoder_destroy(struct drm_encoder *encoder) -{ - return; -} - static struct drm_encoder_funcs imx_hdmi_encoder_funcs = { - .destroy = imx_hdmi_encoder_destroy, + .destroy = imx_drm_encoder_destroy, }; static struct drm_encoder_helper_funcs imx_hdmi_encoder_helper_funcs = { @@ -1493,7 +1482,7 @@ static struct drm_connector_funcs imx_hdmi_connector_funcs = { .dpms = drm_helper_connector_dpms, .fill_modes = drm_helper_probe_single_connector_modes, .detect = imx_hdmi_connector_detect, - .destroy = imx_hdmi_connector_destroy, + .destroy = imx_drm_connector_destroy, }; static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = { @@ -1533,34 +1522,23 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id) return IRQ_HANDLED; } -static int imx_hdmi_register(struct imx_hdmi *hdmi) +static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi) { int ret; - hdmi->connector.funcs = &imx_hdmi_connector_funcs; - hdmi->encoder.funcs = &imx_hdmi_encoder_funcs; - - hdmi->encoder.encoder_type = DRM_MODE_ENCODER_TMDS; - hdmi->connector.connector_type = DRM_MODE_CONNECTOR_HDMIA; + ret = imx_drm_encoder_parse_of(drm, &hdmi->encoder, + hdmi->dev->of_node); + if (ret) + return ret; drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs); - ret = imx_drm_add_encoder(&hdmi->encoder, &hdmi->imx_drm_encoder, - THIS_MODULE); - if (ret) { - dev_err(hdmi->dev, "adding encoder failed: %d\n", ret); - return ret; - } + drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs, +DRM_MODE_ENCODER_TMDS); drm_connector_helper_add(&hdmi->connector, &imx_hdmi_connector_helper_funcs); - - ret = imx_drm_add_connector(&hdmi->connector, - &hdmi->imx_drm_connector, THIS_MODULE); - if (ret) { - imx_drm_remove_encoder(hdmi->imx_drm_encoder); - dev_err(hdmi->dev, "adding connector failed: %d\n", ret); - return ret; - } + drm_connector_init(drm, &hdmi->connector, &imx_hdmi_connector_funcs, + DRM_MODE_CONNECTOR_HDMIA); hdmi->connector.encoder = &hdmi->encoder; @@ -1592,6 +1570,7 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) struct platform_device *pdev = to_platform_device(dev); const struct of_device_id *of_id = of_match_device(imx_hdmi_dt_ids, dev); + struct drm_device *drm = data; struct device_node *np = dev->of_node; struct device_node *ddc_node; struct imx_hdmi *hdmi; @@ -1699,12 +1678,10 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) if (ret) goto err_iahb; - ret = imx_hdmi_register(hdmi); + ret = imx_hdmi_register(drm, hdmi); if (ret) goto err_iahb; - imx_drm_encoder_add_possible_crtcs(hdmi->imx_drm_encoder, np); - dev_set_drvdata(dev, hdmi); return 0; @@ -1721,12 +1698,9 @@ static void imx_hdmi_unbind(struct device *dev, struct device *master, void *data) { struct imx_hdmi *hdmi = dev_get_drvdata(dev); - struct drm_connector *connector = &hdmi->connector; - struct drm_encoder *encoder = &hdmi->encoder; - drm_mode_connector_detach_encoder(connector, encoder); - imx_drm_remove_connector(hdmi->imx_drm_connector); - imx_drm_remove_encoder(hdmi->imx_drm_encoder); + hdmi->connector.fu
[PATCH RFC 37/46] imx-drm: imx-drm-core: remove imx_drm_connector and imx_drm_encoder code
The core imx_drm_connector and imx_drm_encoder code is no longer required - the connectors and encoders are all using the component support, so we can remove this. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 370 drivers/staging/imx-drm/imx-drm.h | 14 -- 2 files changed, 0 insertions(+), 384 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 30d516cc76bb..7872d13689ea 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -40,8 +40,6 @@ struct imx_drm_device { struct drm_device *drm; struct device *dev; struct imx_drm_crtc *crtc[MAX_CRTC]; - struct list_headencoder_list; - struct list_headconnector_list; struct mutexmutex; int pipes; struct drm_fbdev_cma*fbhelper; @@ -56,24 +54,9 @@ struct imx_drm_crtc { int mux_id; }; -struct imx_drm_encoder { - struct drm_encoder *encoder; - struct list_headlist; - struct module *owner; - struct list_headpossible_crtcs; -}; - -struct imx_drm_connector { - struct drm_connector*connector; - struct list_headlist; - struct module *owner; -}; - static int legacyfb_depth = 16; module_param(legacyfb_depth, int, 0444); -static void imx_drm_device_put(void); - int imx_drm_crtc_id(struct imx_drm_crtc *crtc) { return crtc->pipe; @@ -101,8 +84,6 @@ static int imx_drm_driver_unload(struct drm_device *drm) component_unbind_all(drm->dev, drm); - imx_drm_device_put(); - drm_vblank_cleanup(drm); drm_kms_helper_poll_fini(drm); drm_mode_config_cleanup(drm); @@ -234,135 +215,6 @@ static struct imx_drm_device *__imx_drm_device(void) return imx_drm_device; } -static struct drm_device *imx_drm_device_get(void) -{ - struct imx_drm_device *imxdrm = __imx_drm_device(); - struct imx_drm_encoder *enc; - struct imx_drm_connector *con; - - list_for_each_entry(enc, &imxdrm->encoder_list, list) { - if (!try_module_get(enc->owner)) { - dev_err(imxdrm->dev, "could not get module %s\n", - module_name(enc->owner)); - goto unwind_enc; - } - } - - list_for_each_entry(con, &imxdrm->connector_list, list) { - if (!try_module_get(con->owner)) { - dev_err(imxdrm->dev, "could not get module %s\n", - module_name(con->owner)); - goto unwind_con; - } - } - - return imxdrm->drm; - -unwind_con: - list_for_each_entry_continue_reverse(con, &imxdrm->connector_list, list) - module_put(con->owner); -unwind_enc: - list_for_each_entry_continue_reverse(enc, &imxdrm->encoder_list, list) - module_put(enc->owner); - - mutex_unlock(&imxdrm->mutex); - - return NULL; - -} - -static void imx_drm_device_put(void) -{ - struct imx_drm_device *imxdrm = __imx_drm_device(); - struct imx_drm_encoder *enc; - struct imx_drm_connector *con; - - mutex_lock(&imxdrm->mutex); - - list_for_each_entry(con, &imxdrm->connector_list, list) - module_put(con->owner); - - list_for_each_entry(enc, &imxdrm->encoder_list, list) - module_put(enc->owner); - - mutex_unlock(&imxdrm->mutex); -} - -static int drm_mode_group_reinit(struct drm_device *dev) -{ - struct drm_mode_group *group = &dev->primary->mode_group; - uint32_t *id_list = group->id_list; - int ret; - - ret = drm_mode_group_init_legacy_group(dev, group); - if (ret < 0) - return ret; - - kfree(id_list); - return 0; -} - -/* - * register an encoder to the drm core - */ -static int imx_drm_encoder_register(struct imx_drm_encoder *imx_drm_encoder) -{ - struct imx_drm_device *imxdrm = __imx_drm_device(); - - INIT_LIST_HEAD(&imx_drm_encoder->possible_crtcs); - - drm_encoder_init(imxdrm->drm, imx_drm_encoder->encoder, - imx_drm_encoder->encoder->funcs, - imx_drm_encoder->encoder->encoder_type); - - drm_mode_group_reinit(imxdrm->drm); - - return 0; -} - -/* - * unregister an encoder from the drm core - */ -static void imx_drm_encoder_unregister(struct imx_drm_encoder - *imx_drm_encoder) -{ - struct imx_drm_device *imxdrm = __imx_
[PATCH RFC 13/46] imx-drm: imx-hdmi: get rid of pointless fb_reg
fb_reg provides no real benefit to the driver: imx_hdmi_fb_registered() will never be called multiple times. Let's get rid of this. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c |6 -- 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 0cba5d4a9966..267d3c9114c6 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -130,7 +130,6 @@ struct imx_hdmi { int vic; u8 edid[HDMI_EDID_LEN]; - bool fb_reg; bool cable_plugin; bool phy_enabled; @@ -1451,9 +1450,6 @@ static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi) { int ret; - if (hdmi->fb_reg) - return 0; - ret = clk_prepare_enable(hdmi->iahb_clk); if (ret) return ret; @@ -1474,8 +1470,6 @@ static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi) /* Unmute interrupts */ hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); - hdmi->fb_reg = true; - clk_disable_unprepare(hdmi->iahb_clk); return 0; -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 15/46] imx-drm: imx-hdmi: minor cleanups
Some minor cleanups to the HDMI driver. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 1eb12c57aa3e..ee0fceb7b5b2 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -19,7 +19,6 @@ #include #include #include - #include #include @@ -37,7 +36,7 @@ #define YCBCR444 1 #define YCBCR422_16BITS2 #define YCBCR422_8BITS 3 -#defineXVYCC4444 +#define XVYCC444 4 enum hdmi_datamap { RGB444_8B = 0x01, @@ -1762,8 +1761,8 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; struct device_node *ddc_node; struct imx_hdmi *hdmi; - int ret, irq; struct resource *iores; + int ret, irq; hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); if (!hdmi) -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 39/46] imx-drm: imx-drm-core: kill off mutex
This mutex doesn't protect anything anymore; get rid of it. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 26 +++--- 1 files changed, 3 insertions(+), 23 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 10cfea0e948a..0172739a00fe 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -40,14 +40,12 @@ struct imx_drm_device { struct drm_device *drm; struct device *dev; struct imx_drm_crtc *crtc[MAX_CRTC]; - struct mutexmutex; int pipes; struct drm_fbdev_cma*fbhelper; }; struct imx_drm_crtc { struct drm_crtc *crtc; - struct imx_drm_device *imxdrm; int pipe; struct imx_drm_crtc_helper_funcsimx_drm_helper_funcs; struct crtc_cookie cookie; @@ -270,8 +268,6 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) drm_mode_config_init(drm); - mutex_lock(&imxdrm->mutex); - drm_kms_helper_poll_init(drm); ret = drm_vblank_init(drm, MAX_CRTC); @@ -285,12 +281,10 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) */ drm->vblank_disable_allowed = true; - mutex_unlock(&imxdrm->mutex); - /* Now try and bind all our sub-components */ ret = component_bind_all(drm->dev, drm); if (ret) - goto err_relock; + goto err_vblank; /* * All components are now added, we can publish the connector sysfs @@ -330,13 +324,11 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) err_unbind: component_unbind_all(drm->dev, drm); -err_relock: - mutex_lock(&imxdrm->mutex); +err_vblank: drm_vblank_cleanup(drm); err_kms: drm_kms_helper_poll_fini(drm); drm_mode_config_cleanup(drm); - mutex_unlock(&imxdrm->mutex); return ret; } @@ -356,8 +348,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, struct imx_drm_crtc *imx_drm_crtc; int ret; - mutex_lock(&imxdrm->mutex); - /* * The vblank arrays are dimensioned by MAX_CRTC - we can't * pass IDs greater than this to those functions. @@ -384,7 +374,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, imx_drm_crtc->cookie.id = id; imx_drm_crtc->mux_id = imx_drm_crtc->pipe; imx_drm_crtc->crtc = crtc; - imx_drm_crtc->imxdrm = imxdrm; imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc; @@ -400,8 +389,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, drm_crtc_init(drm, crtc, imx_drm_crtc->imx_drm_helper_funcs.crtc_funcs); - mutex_unlock(&imxdrm->mutex); - return 0; err_register: @@ -409,7 +396,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, kfree(imx_drm_crtc); err_alloc: err_busy: - mutex_unlock(&imxdrm->mutex); return ret; } EXPORT_SYMBOL_GPL(imx_drm_add_crtc); @@ -419,16 +405,12 @@ EXPORT_SYMBOL_GPL(imx_drm_add_crtc); */ int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc) { - struct imx_drm_device *imxdrm = imx_drm_crtc->imxdrm; - - mutex_lock(&imxdrm->mutex); + struct imx_drm_device *imxdrm = imx_drm_crtc->crtc->dev->dev_private; drm_crtc_cleanup(imx_drm_crtc->crtc); imxdrm->crtc[imx_drm_crtc->pipe] = NULL; - mutex_unlock(&imxdrm->mutex); - kfree(imx_drm_crtc); return 0; @@ -655,8 +637,6 @@ static int __init imx_drm_init(void) if (!imx_drm_device) return -ENOMEM; - mutex_init(&imx_drm_device->mutex); - ret = platform_driver_register(&imx_drm_pdrv); if (ret) goto err_pdrv; -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 41/46] imx-drm: imx-drm-core: various cleanups
Various cleanups are possible after the previous round of changes; these have no real functional bearing other than tidying up the code. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 47 +++ drivers/staging/imx-drm/imx-drm.h |5 +-- 2 files changed, 19 insertions(+), 33 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 8e257c5fb041..33c020867ed0 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -15,12 +15,12 @@ */ #include #include +#include +#include #include #include #include #include -#include -#include #include #include @@ -28,12 +28,6 @@ #define MAX_CRTC 4 -struct crtc_cookie { - void *cookie; - int id; - struct list_head list; -}; - struct imx_drm_crtc; struct imx_drm_device { @@ -47,7 +41,8 @@ struct imx_drm_crtc { struct drm_crtc *crtc; int pipe; struct imx_drm_crtc_helper_funcsimx_drm_helper_funcs; - struct crtc_cookie cookie; + void*cookie; + int id; int mux_id; }; @@ -271,9 +266,9 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) goto err_kms; /* -* with vblank_disable_allowed = true, vblank interrupt will be disabled -* by drm timer once a current process gives up ownership of -* vblank event.(after drm_vblank_put function is called) +* with vblank_disable_allowed = true, vblank interrupt will be +* disabled by drm timer once a current process gives up ownership +* of vblank event. (after drm_vblank_put function is called) */ drm->vblank_disable_allowed = true; @@ -348,26 +343,20 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, * The vblank arrays are dimensioned by MAX_CRTC - we can't * pass IDs greater than this to those functions. */ - if (imxdrm->pipes >= MAX_CRTC) { - ret = -EINVAL; - goto err_busy; - } + if (imxdrm->pipes >= MAX_CRTC) + return -EINVAL; - if (imxdrm->drm->open_count) { - ret = -EBUSY; - goto err_busy; - } + if (imxdrm->drm->open_count) + return -EBUSY; imx_drm_crtc = kzalloc(sizeof(*imx_drm_crtc), GFP_KERNEL); - if (!imx_drm_crtc) { - ret = -ENOMEM; - goto err_alloc; - } + if (!imx_drm_crtc) + return -ENOMEM; imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs; imx_drm_crtc->pipe = imxdrm->pipes++; - imx_drm_crtc->cookie.cookie = cookie; - imx_drm_crtc->cookie.id = id; + imx_drm_crtc->cookie = cookie; + imx_drm_crtc->id = id; imx_drm_crtc->mux_id = imx_drm_crtc->pipe; imx_drm_crtc->crtc = crtc; @@ -390,8 +379,6 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, err_register: imxdrm->crtc[imx_drm_crtc->pipe] = NULL; kfree(imx_drm_crtc); -err_alloc: -err_busy: return ret; } EXPORT_SYMBOL_GPL(imx_drm_add_crtc); @@ -427,8 +414,8 @@ static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm, for (i = 0; i < MAX_CRTC; i++) { struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i]; - if (imx_drm_crtc && imx_drm_crtc->cookie.id == id && - imx_drm_crtc->cookie.cookie == cookie) + if (imx_drm_crtc && imx_drm_crtc->id == id && + imx_drm_crtc->cookie == cookie) return drm_helper_crtc_possible_mask(imx_drm_crtc->crtc); } diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index c5b97e9ce9a0..0a26222ec539 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -5,13 +5,14 @@ #define IPU_PIX_FMT_GBR24 v4l2_fourcc('G', 'B', 'R', '3') +struct device_node; struct drm_crtc; struct drm_connector; struct drm_device; struct drm_encoder; -struct imx_drm_crtc; struct drm_fbdev_cma; struct drm_framebuffer; +struct imx_drm_crtc; struct platform_device; int imx_drm_crtc_id(struct imx_drm_crtc *crtc); @@ -47,8 +48,6 @@ int imx_drm_panel_format_pins(struct drm_encoder *encoder, int imx_drm_panel_format(struct drm_encoder *encoder, u32 interface_pix_fmt); -struct device_node; - int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder); int imx_drm_encoder_parse_of(struct drm_device *drm, struct drm_encoder *encoder, struct device_node *np); -- 1.7.4.4 ___ devel
[PATCH RFC 19/46] imx-drm: imx-hdmi: clean up setting of vp_conf
Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c | 49 --- 1 files changed, 22 insertions(+), 27 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index f8c652e58a6d..075dd1f0c8a7 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -559,7 +559,7 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) unsigned int remap_size = HDMI_VP_REMAP_YCC422_16bit; unsigned int output_select = HDMI_VP_CONF_OUTPUT_SELECTOR_PP; struct hdmi_data_info *hdmi_data = &hdmi->hdmi_data; - u8 val; + u8 val, vp_conf; if (hdmi_data->enc_out_format == RGB || hdmi_data->enc_out_format == YCBCR444) { @@ -603,47 +603,42 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) /* Data from pixel repeater block */ if (hdmi_data->pix_repet_factor > 1) { - hdmi_modb(hdmi, HDMI_VP_CONF_PR_EN_ENABLE | - HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER, - HDMI_VP_CONF_PR_EN_MASK | - HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF); + vp_conf = HDMI_VP_CONF_PR_EN_ENABLE | + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER; } else { /* data from packetizer block */ - hdmi_modb(hdmi, HDMI_VP_CONF_PR_EN_DISABLE | - HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER, - HDMI_VP_CONF_PR_EN_MASK | - HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF); + vp_conf = HDMI_VP_CONF_PR_EN_DISABLE | + HDMI_VP_CONF_BYPASS_SELECT_VID_PACKETIZER; } + hdmi_modb(hdmi, vp_conf, + HDMI_VP_CONF_PR_EN_MASK | + HDMI_VP_CONF_BYPASS_SELECT_MASK, HDMI_VP_CONF); + hdmi_modb(hdmi, 1 << HDMI_VP_STUFF_IDEFAULT_PHASE_OFFSET, HDMI_VP_STUFF_IDEFAULT_PHASE_MASK, HDMI_VP_STUFF); hdmi_writeb(hdmi, remap_size, HDMI_VP_REMAP); if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_PP) { - hdmi_modb(hdmi, HDMI_VP_CONF_BYPASS_EN_DISABLE | - HDMI_VP_CONF_PP_EN_ENABLE | - HDMI_VP_CONF_YCC422_EN_DISABLE, - HDMI_VP_CONF_BYPASS_EN_MASK | - HDMI_VP_CONF_PP_EN_ENMASK | - HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF); + vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE | + HDMI_VP_CONF_PP_EN_ENABLE | + HDMI_VP_CONF_YCC422_EN_DISABLE; } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_YCC422) { - hdmi_modb(hdmi, HDMI_VP_CONF_BYPASS_EN_DISABLE | - HDMI_VP_CONF_PP_EN_DISABLE | - HDMI_VP_CONF_YCC422_EN_ENABLE, - HDMI_VP_CONF_BYPASS_EN_MASK | - HDMI_VP_CONF_PP_EN_ENMASK | - HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF); + vp_conf = HDMI_VP_CONF_BYPASS_EN_DISABLE | + HDMI_VP_CONF_PP_EN_DISABLE | + HDMI_VP_CONF_YCC422_EN_ENABLE; } else if (output_select == HDMI_VP_CONF_OUTPUT_SELECTOR_BYPASS) { - hdmi_modb(hdmi, HDMI_VP_CONF_BYPASS_EN_ENABLE | - HDMI_VP_CONF_PP_EN_DISABLE | - HDMI_VP_CONF_YCC422_EN_DISABLE, - HDMI_VP_CONF_BYPASS_EN_MASK | - HDMI_VP_CONF_PP_EN_ENMASK | - HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF); + vp_conf = HDMI_VP_CONF_BYPASS_EN_ENABLE | + HDMI_VP_CONF_PP_EN_DISABLE | + HDMI_VP_CONF_YCC422_EN_DISABLE; } else { return; } + hdmi_modb(hdmi, vp_conf, + HDMI_VP_CONF_BYPASS_EN_MASK | HDMI_VP_CONF_PP_EN_ENMASK | + HDMI_VP_CONF_YCC422_EN_MASK, HDMI_VP_CONF); + hdmi_modb(hdmi, HDMI_VP_STUFF_PP_STUFFING_STUFFING_MODE | HDMI_VP_STUFF_YCC422_STUFFING_STUFFING_MODE, HDMI_VP_STUFF_PP_STUFFING_MASK | -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 43/46] imx-drm: imx-hdmi: add hotplug support to HDMI component
Add hotplug support. We have to make the interrupt handler threaded so we can call drm_helper_hpd_irq_event(). Keeping in mind that we will want to share the interrupt with other HDMI interface drivers (eg, audio and CEC) put the groundwork in now for that, rather than just using IRQF_ONESHOT. Also, we must not call drm_helper_hpd_irq_event() until we have fully setup the connector; keep the interrupt(s) muted until after that point. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c | 40 +-- 1 files changed, 33 insertions(+), 7 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 512b39710530..097403a602d8 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -124,6 +124,8 @@ struct imx_hdmi { struct clk *isfr_clk; struct clk *iahb_clk; + enum drm_connector_status connector_status; + struct hdmi_data_info hdmi_data; int vic; @@ -1305,9 +1307,6 @@ static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi) /* Clear Hotplug interrupts */ hdmi_writeb(hdmi, HDMI_IH_PHY_STAT0_HPD, HDMI_IH_PHY_STAT0); - /* Unmute interrupts */ - hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); - return 0; } @@ -1376,8 +1375,9 @@ static void imx_hdmi_poweroff(struct imx_hdmi *hdmi) static enum drm_connector_status imx_hdmi_connector_detect(struct drm_connector *connector, bool force) { - /* FIXME */ - return connector_status_connected; + struct imx_hdmi *hdmi = container_of(connector, struct imx_hdmi, +connector); + return hdmi->connector_status; } static int imx_hdmi_connector_get_modes(struct drm_connector *connector) @@ -1491,6 +1491,18 @@ static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = { .best_encoder = imx_hdmi_connector_best_encoder, }; +static irqreturn_t imx_hdmi_hardirq(int irq, void *dev_id) +{ + struct imx_hdmi *hdmi = dev_id; + u8 intr_stat; + + intr_stat = hdmi_readb(hdmi, HDMI_IH_PHY_STAT0); + if (intr_stat) + hdmi_writeb(hdmi, ~0, HDMI_IH_MUTE_PHY_STAT0); + + return intr_stat ? IRQ_WAKE_THREAD : IRQ_NONE; +} + static irqreturn_t imx_hdmi_irq(int irq, void *dev_id) { struct imx_hdmi *hdmi = dev_id; @@ -1507,17 +1519,21 @@ static irqreturn_t imx_hdmi_irq(int irq, void *dev_id) hdmi_modb(hdmi, 0, HDMI_PHY_HPD, HDMI_PHY_POL0); + hdmi->connector_status = connector_status_connected; imx_hdmi_poweron(hdmi); } else { dev_dbg(hdmi->dev, "EVENT=plugout\n"); hdmi_modb(hdmi, HDMI_PHY_HPD, HDMI_PHY_HPD, HDMI_PHY_POL0); + hdmi->connector_status = connector_status_disconnected; imx_hdmi_poweroff(hdmi); } + drm_helper_hpd_irq_event(hdmi->connector.dev); } hdmi_writeb(hdmi, intr_stat, HDMI_IH_PHY_STAT0); + hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); return IRQ_HANDLED; } @@ -1531,6 +1547,8 @@ static int imx_hdmi_register(struct drm_device *drm, struct imx_hdmi *hdmi) if (ret) return ret; + hdmi->connector.polled = DRM_CONNECTOR_POLL_HPD; + drm_encoder_helper_add(&hdmi->encoder, &imx_hdmi_encoder_helper_funcs); drm_encoder_init(drm, &hdmi->encoder, &imx_hdmi_encoder_funcs, DRM_MODE_ENCODER_TMDS); @@ -1582,6 +1600,7 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) return -ENOMEM; hdmi->dev = dev; + hdmi->connector_status = connector_status_disconnected; hdmi->sample_rate = 48000; hdmi->ratio = 100; @@ -1605,8 +1624,9 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) if (irq < 0) return -EINVAL; - ret = devm_request_irq(dev, irq, imx_hdmi_irq, 0, - dev_name(dev), hdmi); + ret = devm_request_threaded_irq(dev, irq, imx_hdmi_hardirq, + imx_hdmi_irq, IRQF_SHARED, + dev_name(dev), hdmi); if (ret) return ret; @@ -1682,6 +1702,9 @@ static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) if (ret) goto err_iahb; + /* Unmute interrupts */ + hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); + dev_set_drvdata(dev, hdmi); return 0; @@ -1699,6 +1722,9 @@ static void imx_hdmi_unbind(struct device *dev, struct device *master, { struct imx_hdmi *hdmi = dev_g
[PATCH RFC 29/46] imx-drm: delay publishing sysfs connector entries
Delay publishing sysfs connector entries until all components have initialised. This reduces the probability of generating false hotplug events when we're uncertain whether the driver can fully initialise. This also pulls that code out of the individual imx-drm connector drivers. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 22 +- 1 files changed, 21 insertions(+), 1 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 8ece15944569..d5bf4a4646a3 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -355,7 +355,7 @@ static int imx_drm_connector_register( imx_drm_connector->connector->connector_type); drm_mode_group_reinit(imxdrm->drm); - return drm_sysfs_connector_add(imx_drm_connector->connector); + return 0; } /* @@ -379,6 +379,7 @@ static void imx_drm_connector_unregister( static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) { struct imx_drm_device *imxdrm = __imx_drm_device(); + struct drm_connector *connector; int ret; imxdrm->drm = drm; @@ -431,8 +432,27 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) ret = component_bind_all(drm->dev, drm); if (ret) goto err_relock; + + /* +* All components are now added, we can publish the connector sysfs +* entries to userspace. This will generate hotplug events and so +* userspace will expect to be able to access DRM at this point. +*/ + list_for_each_entry(connector, &drm->mode_config.connector_list, head) { + ret = drm_sysfs_connector_add(connector); + if (ret) { + dev_err(drm->dev, + "[CONNECTOR:%d:%s] drm_sysfs_connector_add failed: %d\n", + connector->base.id, + drm_get_connector_name(connector), ret); + goto err_unbind; + } + } + return 0; +err_unbind: + component_unbind_all(drm->dev, drm); err_relock: mutex_lock(&imxdrm->mutex); err_vblank: -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 42/46] imx-drm: imx-drm-core: add core hotplug connector support
Add core imx-drm support for hotplug connector support. We need to setup the poll helper after we've setup the connectors; the helper scans the connectors to determine their capabilities. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 20 1 files changed, 16 insertions(+), 4 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 33c020867ed0..6b86bfeb091f 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -69,6 +69,8 @@ static int imx_drm_driver_unload(struct drm_device *drm) { struct imx_drm_device *imxdrm = drm->dev_private; + drm_kms_helper_poll_fini(drm); + #if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER) if (imxdrm->fbhelper) drm_fbdev_cma_fini(imxdrm->fbhelper); @@ -77,7 +79,6 @@ static int imx_drm_driver_unload(struct drm_device *drm) component_unbind_all(drm->dev, drm); drm_vblank_cleanup(drm); - drm_kms_helper_poll_fini(drm); drm_mode_config_cleanup(drm); return 0; @@ -213,8 +214,19 @@ void imx_drm_encoder_destroy(struct drm_encoder *encoder) } EXPORT_SYMBOL_GPL(imx_drm_encoder_destroy); +static void imx_drm_output_poll_changed(struct drm_device *drm) +{ + struct imx_drm_device *imxdrm = drm->dev_private; + +#if IS_ENABLED(CONFIG_DRM_IMX_FB_HELPER) + if (imxdrm->fbhelper) + drm_fbdev_cma_hotplug_event(imxdrm->fbhelper); +#endif +} + static struct drm_mode_config_funcs imx_drm_mode_config_funcs = { .fb_create = drm_fb_cma_create, + .output_poll_changed = imx_drm_output_poll_changed, }; /* @@ -259,8 +271,6 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) drm_mode_config_init(drm); - drm_kms_helper_poll_init(drm); - ret = drm_vblank_init(drm, MAX_CRTC); if (ret) goto err_kms; @@ -311,6 +321,9 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) goto err_unbind; } #endif + + drm_kms_helper_poll_init(drm); + return 0; err_unbind: @@ -318,7 +331,6 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) err_vblank: drm_vblank_cleanup(drm); err_kms: - drm_kms_helper_poll_fini(drm); drm_mode_config_cleanup(drm); return ret; -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 17/46] imx-drm: imx-hdmi: clean up setting CSC registers
Rather than manually writing each register sequentially, we can use a loop to reduce the amount of code. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c | 40 --- 1 files changed, 14 insertions(+), 26 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 5fda630a798d..dc46d2acd9c5 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -484,6 +484,7 @@ static int is_color_space_interpolation(struct imx_hdmi *hdmi) static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) { const u16 (*csc_coeff)[3][4] = &csc_coeff_default; + unsigned i; u32 csc_scale = 1; u8 val; @@ -502,32 +503,19 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) } } - hdmi_writeb(hdmi, ((*csc_coeff)[0][0] & 0xff), HDMI_CSC_COEF_A1_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[0][0] >> 8), HDMI_CSC_COEF_A1_MSB); - hdmi_writeb(hdmi, ((*csc_coeff)[0][1] & 0xff), HDMI_CSC_COEF_A2_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[0][1] >> 8), HDMI_CSC_COEF_A2_MSB); - hdmi_writeb(hdmi, ((*csc_coeff)[0][2] & 0xff), HDMI_CSC_COEF_A3_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[0][2] >> 8), HDMI_CSC_COEF_A3_MSB); - hdmi_writeb(hdmi, ((*csc_coeff)[0][3] & 0xff), HDMI_CSC_COEF_A4_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[0][3] >> 8), HDMI_CSC_COEF_A4_MSB); - - hdmi_writeb(hdmi, ((*csc_coeff)[1][0] & 0xff), HDMI_CSC_COEF_B1_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[1][0] >> 8), HDMI_CSC_COEF_B1_MSB); - hdmi_writeb(hdmi, ((*csc_coeff)[1][1] & 0xff), HDMI_CSC_COEF_B2_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[1][1] >> 8), HDMI_CSC_COEF_B2_MSB); - hdmi_writeb(hdmi, ((*csc_coeff)[1][2] & 0xff), HDMI_CSC_COEF_B3_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[1][2] >> 8), HDMI_CSC_COEF_B3_MSB); - hdmi_writeb(hdmi, ((*csc_coeff)[1][3] & 0xff), HDMI_CSC_COEF_B4_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[1][3] >> 8), HDMI_CSC_COEF_B4_MSB); - - hdmi_writeb(hdmi, ((*csc_coeff)[2][0] & 0xff), HDMI_CSC_COEF_C1_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[2][0] >> 8), HDMI_CSC_COEF_C1_MSB); - hdmi_writeb(hdmi, ((*csc_coeff)[2][1] & 0xff), HDMI_CSC_COEF_C2_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[2][1] >> 8), HDMI_CSC_COEF_C2_MSB); - hdmi_writeb(hdmi, ((*csc_coeff)[2][2] & 0xff), HDMI_CSC_COEF_C3_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[2][2] >> 8), HDMI_CSC_COEF_C3_MSB); - hdmi_writeb(hdmi, ((*csc_coeff)[2][3] & 0xff), HDMI_CSC_COEF_C4_LSB); - hdmi_writeb(hdmi, ((*csc_coeff)[2][3] >> 8), HDMI_CSC_COEF_C4_MSB); + /* The CSC registers are sequential, alternating MSB then LSB */ + for (i = 0; i < ARRAY_SIZE(csc_coeff_default[0]); i++) { + u16 coeff_a = (*csc_coeff)[0][i]; + u16 coeff_b = (*csc_coeff)[1][i]; + u16 coeff_c = (*csc_coeff)[2][i]; + + hdmi_writeb(hdmi, coeff_a & 0xff, HDMI_CSC_COEF_A1_LSB + i * 2); + hdmi_writeb(hdmi, coeff_a >> 8, HDMI_CSC_COEF_A1_MSB + i * 2); + hdmi_writeb(hdmi, coeff_b & 0xff, HDMI_CSC_COEF_B1_LSB + i * 2); + hdmi_writeb(hdmi, coeff_b >> 8, HDMI_CSC_COEF_B1_MSB + i * 2); + hdmi_writeb(hdmi, coeff_c & 0xff, HDMI_CSC_COEF_C1_LSB + i * 2); + hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2); + } val = hdmi_readb(hdmi, HDMI_CSC_SCALE); val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK; -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 21/46] drm: provide a helper for the encoder possible_crtcs mask
The encoder possible_crtcs mask identifies which CRTCs can be bound to a particular encoder. Each bit from bit 0 defines an index in the list of CRTCs held in the DRM mode_config crtc_list. Rather than having drivers trying to track the position of their CRTCs in the list, expose the code which already exists for calculating the appropriate mask bit for a CRTC. Signed-off-by: Russell King --- drivers/gpu/drm/drm_crtc_helper.c | 39 include/drm/drm_crtc_helper.h |1 + 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 01361aba033b..10708c248196 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c @@ -325,6 +325,29 @@ void drm_helper_disable_unused_functions(struct drm_device *dev) EXPORT_SYMBOL(drm_helper_disable_unused_functions); /** + * drm_helper_crtc_possible_mask - find the mask of a registered CRTC + * @crtc: crtc to find mask for + * + * Given a registered CRTC, return the mask bit of that CRTC for an + * encoder's possible_crtcs field. + */ +uint32_t drm_helper_crtc_possible_mask(struct drm_crtc *crtc) +{ + struct drm_device *dev = crtc->dev; + struct drm_crtc *tmp; + uint32_t crtc_mask = 1; + + list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { + if (tmp == crtc) + return crtc_mask; + crtc_mask <<= 1; + } + + return 0; +} +EXPORT_SYMBOL(drm_helper_crtc_possible_mask); + +/** * drm_encoder_crtc_ok - can a given crtc drive a given encoder? * @encoder: encoder to test * @crtc: crtc to test @@ -334,23 +357,13 @@ EXPORT_SYMBOL(drm_helper_disable_unused_functions); static bool drm_encoder_crtc_ok(struct drm_encoder *encoder, struct drm_crtc *crtc) { - struct drm_device *dev; - struct drm_crtc *tmp; - int crtc_mask = 1; + uint32_t crtc_mask; WARN(!crtc, "checking null crtc?\n"); - dev = crtc->dev; - - list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) { - if (tmp == crtc) - break; - crtc_mask <<= 1; - } + crtc_mask = drm_helper_crtc_possible_mask(crtc); - if (encoder->possible_crtcs & crtc_mask) - return true; - return false; + return !!(encoder->possible_crtcs & crtc_mask); } /* diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index ef6ad3a8e58e..21b9f47dd88c 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h @@ -127,6 +127,7 @@ struct drm_connector_helper_funcs { extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY); extern void drm_helper_disable_unused_functions(struct drm_device *dev); +extern uint32_t drm_helper_crtc_possible_mask(struct drm_crtc *crtc); extern int drm_crtc_helper_set_config(struct drm_mode_set *set); extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode, -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 23/46] imx-drm: imx-drm-core: use array instead of list for CRTCs
The DRM core indexes vblank by number, so there's little point maintaining a list, and have to scan the list to find the appropriate structure. Instead, use an array of pointers to the CRTCs. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 57 +--- 1 files changed, 23 insertions(+), 34 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index a402df0f3005..8aef203a017b 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -34,10 +34,12 @@ struct crtc_cookie { struct list_head list; }; +struct imx_drm_crtc; + struct imx_drm_device { struct drm_device *drm; struct device *dev; - struct list_headcrtc_list; + struct imx_drm_crtc *crtc[MAX_CRTC]; struct list_headencoder_list; struct list_headconnector_list; struct mutexmutex; @@ -47,7 +49,6 @@ struct imx_drm_device { struct imx_drm_crtc { struct drm_crtc *crtc; - struct list_headlist; struct imx_drm_device *imxdrm; int pipe; struct imx_drm_crtc_helper_funcsimx_drm_helper_funcs; @@ -69,6 +70,8 @@ struct imx_drm_connector { struct module *owner; }; +static struct imx_drm_device *__imx_drm_device(void); + int imx_drm_crtc_id(struct imx_drm_crtc *crtc) { return crtc->pipe; @@ -96,34 +99,28 @@ static int imx_drm_driver_unload(struct drm_device *drm) return 0; } -/* - * We don't care at all for crtc numbers, but the core expects the - * crtcs to be numbered - */ -static struct imx_drm_crtc *imx_drm_crtc_by_num(struct imx_drm_device *imxdrm, - int num) +struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) { - struct imx_drm_crtc *imx_drm_crtc; + struct imx_drm_device *imxdrm = __imx_drm_device(); + unsigned i; + + for (i = 0; i < MAX_CRTC; i++) + if (imxdrm->crtc[i] && imxdrm->crtc[i]->crtc == crtc) + return imxdrm->crtc[i]; - list_for_each_entry(imx_drm_crtc, &imxdrm->crtc_list, list) - if (imx_drm_crtc->pipe == num) - return imx_drm_crtc; return NULL; } int imx_drm_crtc_panel_format_pins(struct drm_crtc *crtc, u32 encoder_type, u32 interface_pix_fmt, int hsync_pin, int vsync_pin) { - struct imx_drm_device *imxdrm = crtc->dev->dev_private; - struct imx_drm_crtc *imx_crtc; struct imx_drm_crtc_helper_funcs *helper; + struct imx_drm_crtc *imx_crtc; - list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) - if (imx_crtc->crtc == crtc) - goto found; + imx_crtc = imx_drm_find_crtc(crtc); + if (!imx_crtc) + return -EINVAL; - return -EINVAL; -found: helper = &imx_crtc->imx_drm_helper_funcs; if (helper->set_interface_pix_fmt) return helper->set_interface_pix_fmt(crtc, @@ -162,10 +159,9 @@ EXPORT_SYMBOL_GPL(imx_drm_handle_vblank); static int imx_drm_enable_vblank(struct drm_device *drm, int crtc) { struct imx_drm_device *imxdrm = drm->dev_private; - struct imx_drm_crtc *imx_drm_crtc; + struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[crtc]; int ret; - imx_drm_crtc = imx_drm_crtc_by_num(imxdrm, crtc); if (!imx_drm_crtc) return -EINVAL; @@ -181,9 +177,8 @@ static int imx_drm_enable_vblank(struct drm_device *drm, int crtc) static void imx_drm_disable_vblank(struct drm_device *drm, int crtc) { struct imx_drm_device *imxdrm = drm->dev_private; - struct imx_drm_crtc *imx_drm_crtc; + struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[crtc]; - imx_drm_crtc = imx_drm_crtc_by_num(imxdrm, crtc); if (!imx_drm_crtc) return; @@ -509,7 +504,7 @@ int imx_drm_add_crtc(struct drm_crtc *crtc, imx_drm_crtc->owner = owner; - list_add_tail(&imx_drm_crtc->list, &imxdrm->crtc_list); + imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc; *new_crtc = imx_drm_crtc; @@ -532,7 +527,7 @@ int imx_drm_add_crtc(struct drm_crtc *crtc, return 0; err_register: - list_del(&imx_drm_crtc->list); + imxdrm->crtc[imx_drm_crtc->pipe] = NULL; kfree(imx_drm_crtc); err_alloc: err_busy: @@ -552,7 +547,7 @@ int imx_drm_remove_crtc(struct imx_drm_crtc *imx_drm_crtc) drm_crtc_cleanup(imx_drm_crtc->crtc); - list_del(&imx_drm_crtc->list); + imxdrm->crtc[imx_drm_crtc->pipe] = NULL; drm_mode_group_reinit(imxdrm->drm); @@ -659,14 +654,9
[PATCH RFC 18/46] imx-drm: imx-hdmi: provide register modification function
There are a load of read-modify-write patterns to change bitfields in various registers in this driver; provide a helper to perform this manipulation. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c | 188 +--- 1 files changed, 68 insertions(+), 120 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index dc46d2acd9c5..f8c652e58a6d 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -160,37 +160,34 @@ static inline u8 hdmi_readb(struct imx_hdmi *hdmi, int offset) return readb(hdmi->regs + offset); } +static void hdmi_modb(struct imx_hdmi *hdmi, u8 data, u8 mask, unsigned reg) +{ + u8 val = hdmi_readb(hdmi, reg) & ~mask; + val |= data & mask; + hdmi_writeb(hdmi, val, reg); +} + static void hdmi_mask_writeb(struct imx_hdmi *hdmi, u8 data, unsigned int reg, u8 shift, u8 mask) { - u8 value = hdmi_readb(hdmi, reg) & ~mask; - value |= (data << shift) & mask; - hdmi_writeb(hdmi, value, reg); + hdmi_modb(hdmi, data << shift, mask, reg); } static void hdmi_set_clock_regenerator_n(struct imx_hdmi *hdmi, unsigned int value) { - u8 val; - hdmi_writeb(hdmi, value & 0xff, HDMI_AUD_N1); hdmi_writeb(hdmi, (value >> 8) & 0xff, HDMI_AUD_N2); hdmi_writeb(hdmi, (value >> 16) & 0x0f, HDMI_AUD_N3); /* nshift factor = 0 */ - val = hdmi_readb(hdmi, HDMI_AUD_CTS3); - val &= ~HDMI_AUD_CTS3_N_SHIFT_MASK; - hdmi_writeb(hdmi, val, HDMI_AUD_CTS3); + hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_N_SHIFT_MASK, HDMI_AUD_CTS3); } static void hdmi_regenerate_cts(struct imx_hdmi *hdmi, unsigned int cts) { - u8 val; - /* Must be set/cleared first */ - val = hdmi_readb(hdmi, HDMI_AUD_CTS3); - val &= ~HDMI_AUD_CTS3_CTS_MANUAL; - hdmi_writeb(hdmi, val, HDMI_AUD_CTS3); + hdmi_modb(hdmi, 0, HDMI_AUD_CTS3_CTS_MANUAL, HDMI_AUD_CTS3); hdmi_writeb(hdmi, cts & 0xff, HDMI_AUD_CTS1); hdmi_writeb(hdmi, (cts >> 8) & 0xff, HDMI_AUD_CTS2); @@ -486,7 +483,6 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) const u16 (*csc_coeff)[3][4] = &csc_coeff_default; unsigned i; u32 csc_scale = 1; - u8 val; if (is_color_space_conversion(hdmi)) { if (hdmi->hdmi_data.enc_out_format == RGB) { @@ -517,10 +513,8 @@ static void imx_hdmi_update_csc_coeffs(struct imx_hdmi *hdmi) hdmi_writeb(hdmi, coeff_c >> 8, HDMI_CSC_COEF_C1_MSB + i * 2); } - val = hdmi_readb(hdmi, HDMI_CSC_SCALE); - val &= ~HDMI_CSC_SCALE_CSCSCALE_MASK; - val |= csc_scale & HDMI_CSC_SCALE_CSCSCALE_MASK; - hdmi_writeb(hdmi, val, HDMI_CSC_SCALE); + hdmi_modb(hdmi, csc_scale, HDMI_CSC_SCALE_CSCSCALE_MASK, + HDMI_CSC_SCALE); } static void hdmi_video_csc(struct imx_hdmi *hdmi) @@ -528,7 +522,6 @@ static void hdmi_video_csc(struct imx_hdmi *hdmi) int color_depth = 0; int interpolation = HDMI_CSC_CFG_INTMODE_DISABLE; int decimation = 0; - u8 val; /* YCC422 interpolation to 444 mode */ if (is_color_space_interpolation(hdmi)) @@ -549,10 +542,8 @@ static void hdmi_video_csc(struct imx_hdmi *hdmi) /* Configure the CSC registers */ hdmi_writeb(hdmi, interpolation | decimation, HDMI_CSC_CFG); - val = hdmi_readb(hdmi, HDMI_CSC_SCALE); - val &= ~HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK; - val |= color_depth; - hdmi_writeb(hdmi, val, HDMI_CSC_SCALE); + hdmi_modb(hdmi, color_depth, HDMI_CSC_SCALE_CSC_COLORDE_PTH_MASK, + HDMI_CSC_SCALE); imx_hdmi_update_csc_coeffs(hdmi); } @@ -607,107 +598,80 @@ static void hdmi_video_packetize(struct imx_hdmi *hdmi) HDMI_VP_PR_CD_DESIRED_PR_FACTOR_MASK); hdmi_writeb(hdmi, val, HDMI_VP_PR_CD); - val = hdmi_readb(hdmi, HDMI_VP_STUFF); - val &= ~HDMI_VP_STUFF_PR_STUFFING_MASK; - val |= HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE; - hdmi_writeb(hdmi, val, HDMI_VP_STUFF); + hdmi_modb(hdmi, HDMI_VP_STUFF_PR_STUFFING_STUFFING_MODE, + HDMI_VP_STUFF_PR_STUFFING_MASK, HDMI_VP_STUFF); /* Data from pixel repeater block */ if (hdmi_data->pix_repet_factor > 1) { - val = hdmi_readb(hdmi, HDMI_VP_CONF); - val &= ~(HDMI_VP_CONF_PR_EN_MASK | - HDMI_VP_CONF_BYPASS_SELECT_MASK); - val |= HDMI_VP_CONF_PR_EN_ENABLE | - HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER; - hdmi_writeb(hdmi, val, HDMI_VP_CONF); + hdmi_modb(hdmi, HDMI_VP_CONF_PR_EN_ENABLE | + HDMI_VP_CONF_BYPASS_SELECT_PIX_REPEATER, + HDMI_VP_CONF_PR_EN_MASK | +
[PATCH RFC 22/46] imx-drm: imx-drm-core: sanitise imx_drm_encoder_get_mux_id()
Address the following issues: - imx_drm_encoder_get_mux_id() searches the CRTC list for the matching CRTC, and returns the position within this list as the MUX programming value for encoders. This is sub-optimal for two reasons: 1. It relies upon the CRTC list not changing during the lifetime of the driver. 2. It is dependent on the initialisation order of the CRTCs. We address (1) in this patch, leaving (2) until a better solution can be found, as (2) requires larger changes. - imx_drm_encoder is unused. Instead, pass the drm_encoder which is slightly more useful; all callers pass encoder->crtc as the required crtc, so move this inside the function. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 17 ++--- drivers/staging/imx-drm/imx-drm.h |3 +-- drivers/staging/imx-drm/imx-hdmi.c |3 +-- drivers/staging/imx-drm/imx-ldb.c |6 ++ 4 files changed, 10 insertions(+), 19 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 05dd24ee80dd..a402df0f3005 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -53,6 +53,7 @@ struct imx_drm_crtc { struct imx_drm_crtc_helper_funcsimx_drm_helper_funcs; struct module *owner; struct crtc_cookie cookie; + int mux_id; }; struct imx_drm_encoder { @@ -502,7 +503,7 @@ int imx_drm_add_crtc(struct drm_crtc *crtc, imx_drm_crtc->pipe = imxdrm->pipes++; imx_drm_crtc->cookie.cookie = cookie; imx_drm_crtc->cookie.id = id; - + imx_drm_crtc->mux_id = imx_drm_crtc->pipe; imx_drm_crtc->crtc = crtc; imx_drm_crtc->imxdrm = imxdrm; @@ -656,22 +657,16 @@ int imx_drm_encoder_add_possible_crtcs( } EXPORT_SYMBOL_GPL(imx_drm_encoder_add_possible_crtcs); -int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder, - struct drm_crtc *crtc) +int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder) { struct imx_drm_device *imxdrm = __imx_drm_device(); struct imx_drm_crtc *imx_crtc; - int i = 0; - list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) { - if (imx_crtc->crtc == crtc) - goto found; - i++; - } + list_for_each_entry(imx_crtc, &imxdrm->crtc_list, list) + if (imx_crtc->crtc == encoder->crtc) + return imx_crtc->mux_id; return -EINVAL; -found: - return i; } EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id); diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index ae90c9c15312..5649f180dc44 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -64,8 +64,7 @@ void imx_drm_fb_helper_set(struct drm_fbdev_cma *fbdev_helper); struct device_node; -int imx_drm_encoder_get_mux_id(struct imx_drm_encoder *imx_drm_encoder, - struct drm_crtc *crtc); +int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder); int imx_drm_encoder_add_possible_crtcs(struct imx_drm_encoder *imx_drm_encoder, struct device_node *np); diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 2eb51e7ea9bb..c8152043143f 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1471,8 +1471,7 @@ static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder) static void imx_hdmi_encoder_commit(struct drm_encoder *encoder) { struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); - int mux = imx_drm_encoder_get_mux_id(hdmi->imx_drm_encoder, -encoder->crtc); + int mux = imx_drm_encoder_get_mux_id(encoder); imx_hdmi_set_ipu_di_mux(hdmi, mux); diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 654bf03e05ff..bbcbd52f0169 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -180,8 +180,7 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) u32 pixel_fmt; unsigned long serial_clk; unsigned long di_clk = mode->clock * 1000; - int mux = imx_drm_encoder_get_mux_id(imx_ldb_ch->imx_drm_encoder, -encoder->crtc); + int mux = imx_drm_encoder_get_mux_id(encoder); if (ldb->ldb_ctrl & LDB_SPLIT_MODE_EN) { /* dual channel LVDS mode */ @@ -217,8 +216,7 @@ static void imx_ldb_encoder_commit(struct drm_encoder *encoder) struct imx_ldb_channel *imx_ldb_ch = enc_to_imx_ldb_ch(encoder); struct imx_ldb *ldb = imx_ldb_ch->ldb; int dual = ldb->ldb_ctrl & LDB_SPLIT_MODE_EN; - int mux = imx_drm_encoder_get_mux_id(imx_l
[PATCH RFC 46/46] imx-drm: pass an IPU ID to crtc and core (needs work)
On IMX6D/Q devices, the display bridge muxes can select either display interface on either of the IPUs. Therefore, we need to positively know which IPU each CRTC is. We partially solve this by passing an IPU ID from the IPUv3 driver into the DRM CRTC driver, which also passes it into the core code. This gives a method by which we can try to solve this. However, we're still stuck with trying to guess the IPU ID in the IPU driver as we don't have a positive way to identify this. This needs to be resolved. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 14 +++--- drivers/staging/imx-drm/imx-drm.h |2 +- drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h |1 + drivers/staging/imx-drm/ipu-v3/ipu-common.c | 15 +++ drivers/staging/imx-drm/ipuv3-crtc.c|7 +++ 5 files changed, 23 insertions(+), 16 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 6b86bfeb091f..2490dc32df4a 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -42,8 +42,8 @@ struct imx_drm_crtc { int pipe; struct imx_drm_crtc_helper_funcsimx_drm_helper_funcs; void*cookie; - int id; - int mux_id; + int di_id; + int ipu_id; }; static int legacyfb_depth = 16; @@ -345,7 +345,7 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, struct imx_drm_crtc **new_crtc, const struct imx_drm_crtc_helper_funcs *imx_drm_helper_funcs, - void *cookie, int id) + void *cookie, int ipu_id, int di_id) { struct imx_drm_device *imxdrm = drm->dev_private; struct imx_drm_crtc *imx_drm_crtc; @@ -368,8 +368,8 @@ int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, imx_drm_crtc->imx_drm_helper_funcs = *imx_drm_helper_funcs; imx_drm_crtc->pipe = imxdrm->pipes++; imx_drm_crtc->cookie = cookie; - imx_drm_crtc->id = id; - imx_drm_crtc->mux_id = imx_drm_crtc->pipe; + imx_drm_crtc->di_id = di_id; + imx_drm_crtc->ipu_id = ipu_id; imx_drm_crtc->crtc = crtc; imxdrm->crtc[imx_drm_crtc->pipe] = imx_drm_crtc; @@ -426,7 +426,7 @@ static uint32_t imx_drm_find_crtc_mask(struct imx_drm_device *imxdrm, for (i = 0; i < MAX_CRTC; i++) { struct imx_drm_crtc *imx_drm_crtc = imxdrm->crtc[i]; - if (imx_drm_crtc && imx_drm_crtc->id == id && + if (imx_drm_crtc && imx_drm_crtc->di_id == id && imx_drm_crtc->cookie == cookie) return drm_helper_crtc_possible_mask(imx_drm_crtc->crtc); } @@ -482,7 +482,7 @@ int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder) { struct imx_drm_crtc *imx_crtc = imx_drm_find_crtc(encoder->crtc); - return imx_crtc ? imx_crtc->mux_id : -EINVAL; + return imx_crtc ? imx_crtc->ipu_id * 2 + imx_crtc->di_id : -EINVAL; } EXPORT_SYMBOL_GPL(imx_drm_encoder_get_mux_id); diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index 0a26222ec539..7d8d9634a4db 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -29,7 +29,7 @@ struct imx_drm_crtc_helper_funcs { int imx_drm_add_crtc(struct drm_device *drm, struct drm_crtc *crtc, struct imx_drm_crtc **new_crtc, const struct imx_drm_crtc_helper_funcs *imx_helper_funcs, - void *cookie, int id); + void *cookie, int ipu_id, int di_id); int imx_drm_remove_crtc(struct imx_drm_crtc *); int imx_drm_init_drm(struct platform_device *pdev, int preferred_bpp); diff --git a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h index 4826b5c0249d..7b879ace4feb 100644 --- a/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h +++ b/drivers/staging/imx-drm/ipu-v3/imx-ipu-v3.h @@ -319,6 +319,7 @@ struct ipu_client_platformdata { int dp; int dmfc; int dma[2]; + int ipu; }; #endif /* __DRM_IPU_H__ */ diff --git a/drivers/staging/imx-drm/ipu-v3/ipu-common.c b/drivers/staging/imx-drm/ipu-v3/ipu-common.c index 97ca6924dbb3..96b1135b1181 100644 --- a/drivers/staging/imx-drm/ipu-v3/ipu-common.c +++ b/drivers/staging/imx-drm/ipu-v3/ipu-common.c @@ -1003,19 +1003,26 @@ static int ipu_add_client_devices(struct ipu_soc *ipu) { struct device *dev = ipu->dev; unsigned i; - int id, ret; + int ipu_id, id, ret; mutex_lock(&ipu_client_id_mutex); - id = ipu_client_id; -
[PATCH RFC 24/46] imx-drm: provide common connector mode validation function
Provide a common connector mode validation function, which can be used to limit the available modes according to other components in the system. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c |7 +++ drivers/staging/imx-drm/imx-drm.h |3 +++ drivers/staging/imx-drm/imx-hdmi.c |9 + drivers/staging/imx-drm/imx-ldb.c |8 +--- drivers/staging/imx-drm/imx-tve.c |5 + drivers/staging/imx-drm/parallel-display.c |8 +--- 6 files changed, 18 insertions(+), 22 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 8aef203a017b..d7cb0af9479a 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -211,6 +211,13 @@ static const struct file_operations imx_drm_driver_fops = { .llseek = noop_llseek, }; +int imx_drm_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode) +{ + return MODE_OK; +} +EXPORT_SYMBOL(imx_drm_connector_mode_valid); + static struct imx_drm_device *imx_drm_device; static struct imx_drm_device *__imx_drm_device(void) diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index 5649f180dc44..4eb594ce9cff 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -68,4 +68,7 @@ int imx_drm_encoder_get_mux_id(struct drm_encoder *encoder); int imx_drm_encoder_add_possible_crtcs(struct imx_drm_encoder *imx_drm_encoder, struct device_node *np); +int imx_drm_connector_mode_valid(struct drm_connector *connector, + struct drm_display_mode *mode); + #endif /* _IMX_DRM_H_ */ diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index c8152043143f..8421c715ce14 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1410,13 +1410,6 @@ static int imx_hdmi_connector_get_modes(struct drm_connector *connector) return 0; } -static int imx_hdmi_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - - return MODE_OK; -} - static struct drm_encoder *imx_hdmi_connector_best_encoder(struct drm_connector *connector) { @@ -1505,7 +1498,7 @@ static struct drm_connector_funcs imx_hdmi_connector_funcs = { static struct drm_connector_helper_funcs imx_hdmi_connector_helper_funcs = { .get_modes = imx_hdmi_connector_get_modes, - .mode_valid = imx_hdmi_connector_mode_valid, + .mode_valid = imx_drm_connector_mode_valid, .best_encoder = imx_hdmi_connector_best_encoder, }; diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index bbcbd52f0169..81a23685b42d 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -120,12 +120,6 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) return num_modes; } -static int imx_ldb_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - return 0; -} - static struct drm_encoder *imx_ldb_connector_best_encoder( struct drm_connector *connector) { @@ -330,7 +324,7 @@ static struct drm_connector_funcs imx_ldb_connector_funcs = { static struct drm_connector_helper_funcs imx_ldb_connector_helper_funcs = { .get_modes = imx_ldb_connector_get_modes, .best_encoder = imx_ldb_connector_best_encoder, - .mode_valid = imx_ldb_connector_mode_valid, + .mode_valid = imx_drm_connector_mode_valid, }; static struct drm_encoder_funcs imx_ldb_encoder_funcs = { diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/staging/imx-drm/imx-tve.c index 2c44fef8d58b..f315c5250fe8 100644 --- a/drivers/staging/imx-drm/imx-tve.c +++ b/drivers/staging/imx-drm/imx-tve.c @@ -254,6 +254,11 @@ static int imx_tve_connector_mode_valid(struct drm_connector *connector, { struct imx_tve *tve = con_to_tve(connector); unsigned long rate; + int ret; + + ret = imx_drm_connector_mode_valid(connector, mode); + if (ret != MODE_OK) + return ret; /* pixel clock with 2x oversampling */ rate = clk_round_rate(tve->clk, 2000UL * mode->clock) / 2000; diff --git a/drivers/staging/imx-drm/parallel-display.c b/drivers/staging/imx-drm/parallel-display.c index 24aa9beedcfb..789950b87b29 100644 --- a/drivers/staging/imx-drm/parallel-display.c +++ b/drivers/staging/imx-drm/parallel-display.c @@ -84,12 +84,6 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) return num_modes; } -static int imx_pd_connector_mode_valid(struct drm_connector *connector, - struct drm_display_mode *mode) -{ - return 0; -} - static struct drm_en
[PATCH RFC 28/46] imx-drm: imx-hdmi: convert to a component device
Convert imx-hdmi to be a component device; it will bind and unbind at the appropriate moment in the main DRM driver's functions. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c | 41 +-- 1 files changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 0e5e7a6f6168..d81940a8904f 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -12,6 +12,7 @@ * Copyright (C) 2010, Guennadi Liakhovetski */ +#include #include #include #include @@ -1586,21 +1587,22 @@ static const struct of_device_id imx_hdmi_dt_ids[] = { }; MODULE_DEVICE_TABLE(of, imx_hdmi_dt_ids); -static int imx_hdmi_platform_probe(struct platform_device *pdev) +static int imx_hdmi_bind(struct device *dev, struct device *master, void *data) { + struct platform_device *pdev = to_platform_device(dev); const struct of_device_id *of_id = - of_match_device(imx_hdmi_dt_ids, &pdev->dev); - struct device_node *np = pdev->dev.of_node; + of_match_device(imx_hdmi_dt_ids, dev); + struct device_node *np = dev->of_node; struct device_node *ddc_node; struct imx_hdmi *hdmi; struct resource *iores; int ret, irq; - hdmi = devm_kzalloc(&pdev->dev, sizeof(*hdmi), GFP_KERNEL); + hdmi = devm_kzalloc(dev, sizeof(*hdmi), GFP_KERNEL); if (!hdmi) return -ENOMEM; - hdmi->dev = &pdev->dev; + hdmi->dev = dev; hdmi->sample_rate = 48000; hdmi->ratio = 100; @@ -1624,13 +1626,13 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) if (irq < 0) return -EINVAL; - ret = devm_request_irq(&pdev->dev, irq, imx_hdmi_irq, 0, - dev_name(&pdev->dev), hdmi); + ret = devm_request_irq(dev, irq, imx_hdmi_irq, 0, + dev_name(dev), hdmi); if (ret) return ret; iores = platform_get_resource(pdev, IORESOURCE_MEM, 0); - hdmi->regs = devm_ioremap_resource(&pdev->dev, iores); + hdmi->regs = devm_ioremap_resource(dev, iores); if (IS_ERR(hdmi->regs)) return PTR_ERR(hdmi->regs); @@ -1669,7 +1671,7 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) } /* Product and revision IDs */ - dev_info(&pdev->dev, + dev_info(dev, "Detected HDMI controller 0x%x:0x%x:0x%x:0x%x\n", hdmi_readb(hdmi, HDMI_DESIGN_ID), hdmi_readb(hdmi, HDMI_REVISION_ID), @@ -1703,7 +1705,7 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) imx_drm_encoder_add_possible_crtcs(hdmi->imx_drm_encoder, np); - platform_set_drvdata(pdev, hdmi); + dev_set_drvdata(dev, hdmi); return 0; @@ -1715,9 +1717,10 @@ static int imx_hdmi_platform_probe(struct platform_device *pdev) return ret; } -static int imx_hdmi_platform_remove(struct platform_device *pdev) +static void imx_hdmi_unbind(struct device *dev, struct device *master, + void *data) { - struct imx_hdmi *hdmi = platform_get_drvdata(pdev); + struct imx_hdmi *hdmi = dev_get_drvdata(dev); struct drm_connector *connector = &hdmi->connector; struct drm_encoder *encoder = &hdmi->encoder; @@ -1728,7 +1731,21 @@ static int imx_hdmi_platform_remove(struct platform_device *pdev) clk_disable_unprepare(hdmi->iahb_clk); clk_disable_unprepare(hdmi->isfr_clk); i2c_put_adapter(hdmi->ddc); +} +static const struct component_ops hdmi_ops = { + .bind = imx_hdmi_bind, + .unbind = imx_hdmi_unbind, +}; + +static int imx_hdmi_platform_probe(struct platform_device *pdev) +{ + return component_add(&pdev->dev, &hdmi_ops); +} + +static int imx_hdmi_platform_remove(struct platform_device *pdev) +{ + component_del(&pdev->dev, &hdmi_ops); return 0; } -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 25/46] imx-drm: simplify setup of panel format
The encoder format passed into imx_drm_crtc_panel_format*() is the encoder format used for DRM in most cases; the HDMI encoder sets this to none, but this is incorrect, it should be TMDS. Since this is the case, we can pass the drm_encoder structure directly into this function and use the supplied fields there to configure the CRTC. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c | 18 -- drivers/staging/imx-drm/imx-drm.h |4 ++-- drivers/staging/imx-drm/imx-hdmi.c |3 +-- drivers/staging/imx-drm/imx-ldb.c |3 +-- drivers/staging/imx-drm/imx-tve.c | 12 +++- drivers/staging/imx-drm/ipuv3-crtc.c |1 + drivers/staging/imx-drm/parallel-display.c |3 +-- 7 files changed, 21 insertions(+), 23 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index d7cb0af9479a..839dbb7c7b36 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -111,32 +111,30 @@ struct imx_drm_crtc *imx_drm_find_crtc(struct drm_crtc *crtc) return NULL; } -int imx_drm_crtc_panel_format_pins(struct drm_crtc *crtc, u32 encoder_type, +int imx_drm_panel_format_pins(struct drm_encoder *encoder, u32 interface_pix_fmt, int hsync_pin, int vsync_pin) { struct imx_drm_crtc_helper_funcs *helper; struct imx_drm_crtc *imx_crtc; - imx_crtc = imx_drm_find_crtc(crtc); + imx_crtc = imx_drm_find_crtc(encoder->crtc); if (!imx_crtc) return -EINVAL; helper = &imx_crtc->imx_drm_helper_funcs; if (helper->set_interface_pix_fmt) - return helper->set_interface_pix_fmt(crtc, - encoder_type, interface_pix_fmt, + return helper->set_interface_pix_fmt(encoder->crtc, + encoder->encoder_type, interface_pix_fmt, hsync_pin, vsync_pin); return 0; } -EXPORT_SYMBOL_GPL(imx_drm_crtc_panel_format_pins); +EXPORT_SYMBOL_GPL(imx_drm_panel_format_pins); -int imx_drm_crtc_panel_format(struct drm_crtc *crtc, u32 encoder_type, - u32 interface_pix_fmt) +int imx_drm_panel_format(struct drm_encoder *encoder, u32 interface_pix_fmt) { - return imx_drm_crtc_panel_format_pins(crtc, encoder_type, - interface_pix_fmt, 2, 3); + return imx_drm_panel_format_pins(encoder, interface_pix_fmt, 2, 3); } -EXPORT_SYMBOL_GPL(imx_drm_crtc_panel_format); +EXPORT_SYMBOL_GPL(imx_drm_panel_format); int imx_drm_crtc_vblank_get(struct imx_drm_crtc *imx_drm_crtc) { diff --git a/drivers/staging/imx-drm/imx-drm.h b/drivers/staging/imx-drm/imx-drm.h index 4eb594ce9cff..e3ca0c6b6a39 100644 --- a/drivers/staging/imx-drm/imx-drm.h +++ b/drivers/staging/imx-drm/imx-drm.h @@ -56,9 +56,9 @@ struct drm_gem_cma_object *imx_drm_fb_get_obj(struct drm_framebuffer *fb); struct drm_device *imx_drm_device_get(void); void imx_drm_device_put(void); -int imx_drm_crtc_panel_format_pins(struct drm_crtc *crtc, u32 encoder_type, +int imx_drm_panel_format_pins(struct drm_encoder *encoder, u32 interface_pix_fmt, int hsync_pin, int vsync_pin); -int imx_drm_crtc_panel_format(struct drm_crtc *crtc, u32 encoder_type, +int imx_drm_panel_format(struct drm_encoder *encoder, u32 interface_pix_fmt); void imx_drm_fb_helper_set(struct drm_fbdev_cma *fbdev_helper); diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 8421c715ce14..0e5e7a6f6168 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1457,8 +1457,7 @@ static void imx_hdmi_encoder_prepare(struct drm_encoder *encoder) struct imx_hdmi *hdmi = container_of(encoder, struct imx_hdmi, encoder); imx_hdmi_poweroff(hdmi); - imx_drm_crtc_panel_format(encoder->crtc, DRM_MODE_ENCODER_NONE, - V4L2_PIX_FMT_RGB24); + imx_drm_panel_format(encoder, V4L2_PIX_FMT_RGB24); } static void imx_hdmi_encoder_commit(struct drm_encoder *encoder) diff --git a/drivers/staging/imx-drm/imx-ldb.c b/drivers/staging/imx-drm/imx-ldb.c index 81a23685b42d..70455c4d7e48 100644 --- a/drivers/staging/imx-drm/imx-ldb.c +++ b/drivers/staging/imx-drm/imx-ldb.c @@ -201,8 +201,7 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) pixel_fmt = V4L2_PIX_FMT_RGB24; } - imx_drm_crtc_panel_format(encoder->crtc, DRM_MODE_ENCODER_LVDS, - pixel_fmt); + imx_drm_panel_format(encoder, pixel_fmt); } static void imx_ldb_encoder_commit(struct drm_encoder *encoder) diff --git a/drivers/staging/imx-drm/imx-tve.c b/drivers/staging/imx-drm/imx-tve.c index f315c5250fe8..b2f214971501 100644 --- a/drivers/staging/imx-drm/imx-tve.c +++ b/drivers/staging/imx-drm/imx-tve.c @@ -3
[PATCH RFC 27/46] imx-drm: convert to componentised device support
Use the componentised device support for imx-drm. This requires all the sub-components and the master device to register with the component device support. Signed-off-by: Russell King --- arch/arm/boot/dts/imx51-babbage.dts| 10 ++- arch/arm/boot/dts/imx53-m53evk.dts |8 ++- arch/arm/boot/dts/imx53-mba53.dts |6 ++ arch/arm/boot/dts/imx53-qsb.dts|8 ++- arch/arm/boot/dts/imx6qdl-sabresd.dtsi |6 ++ drivers/staging/imx-drm/imx-drm-core.c | 105 ++- drivers/staging/imx-drm/imx-ldb.c | 40 --- drivers/staging/imx-drm/imx-tve.c | 63 +++-- drivers/staging/imx-drm/ipuv3-crtc.c | 46 + drivers/staging/imx-drm/parallel-display.c | 30 ++-- 10 files changed, 242 insertions(+), 80 deletions(-) diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index be1407cf5abd..6ff15a0eacb3 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts @@ -21,7 +21,7 @@ reg = <0x9000 0x2000>; }; - display@di0 { + display0: display@di0 { compatible = "fsl,imx-parallel-display"; crtcs = <&ipu 0>; interface-pix-fmt = "rgb24"; @@ -43,7 +43,7 @@ }; }; - display@di1 { + display1: display@di1 { compatible = "fsl,imx-parallel-display"; crtcs = <&ipu 1>; interface-pix-fmt = "rgb565"; @@ -81,6 +81,12 @@ }; }; + imx-drm { + compatible = "fsl,imx-drm"; + crtcs = <&ipu 0>, <&ipu 1>; + connectors = <&display0>, <&display1>; + }; + sound { compatible = "fsl,imx51-babbage-sgtl5000", "fsl,imx-audio-sgtl5000"; diff --git a/arch/arm/boot/dts/imx53-m53evk.dts b/arch/arm/boot/dts/imx53-m53evk.dts index 7d304d02ed38..ee6107b6484c 100644 --- a/arch/arm/boot/dts/imx53-m53evk.dts +++ b/arch/arm/boot/dts/imx53-m53evk.dts @@ -21,7 +21,7 @@ }; soc { - display@di1 { + display1: display@di1 { compatible = "fsl,imx-parallel-display"; crtcs = <&ipu 1>; interface-pix-fmt = "bgr666"; @@ -53,6 +53,12 @@ default-brightness-level = <6>; }; + imx-drm { + compatible = "fsl,imx-drm"; + crtcs = <&ipu 1>; + connectors = <&display1>; + }; + leds { compatible = "gpio-leds"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/imx53-mba53.dts b/arch/arm/boot/dts/imx53-mba53.dts index a63090267941..9b6e76980a74 100644 --- a/arch/arm/boot/dts/imx53-mba53.dts +++ b/arch/arm/boot/dts/imx53-mba53.dts @@ -43,6 +43,12 @@ status = "disabled"; }; + imx-drm { + compatible = "fsl,imx-drm"; + crtcs = <&ipu 1>; + connectors = <&disp1>, <&tve>; + }; + reg_3p2v: 3p2v { compatible = "regulator-fixed"; regulator-name = "3P2V"; diff --git a/arch/arm/boot/dts/imx53-qsb.dts b/arch/arm/boot/dts/imx53-qsb.dts index 91a5935a4aac..3cb4f7791a91 100644 --- a/arch/arm/boot/dts/imx53-qsb.dts +++ b/arch/arm/boot/dts/imx53-qsb.dts @@ -21,7 +21,7 @@ reg = <0x7000 0x4000>; }; - display@di0 { + display0: display@di0 { compatible = "fsl,imx-parallel-display"; crtcs = <&ipu 0>; interface-pix-fmt = "rgb565"; @@ -72,6 +72,12 @@ }; }; + imx-drm { + compatible = "fsl,imx-drm"; + crtcs = <&ipu 0>; + connectors = <&display0>; + }; + leds { compatible = "gpio-leds"; pinctrl-names = "default"; diff --git a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi index e75e11b36dff..0e005f21d241 100644 --- a/arch/arm/boot/dts/imx6qdl-sabresd.dtsi +++ b/arch/arm/boot/dts/imx6qdl-sabresd.dtsi @@ -62,6 +62,12 @@ }; }; + imx-drm { + compatible = "fsl,imx-drm"; + crtcs = <&ipu1 0>, <&ipu1 1>; + connectors = <&ldb>; + }; + sound { compatible = "fsl,imx6q-sabresd-wm8962", "fsl,imx-audio-wm8962"; diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 839dbb7c7b36..8ece15944569 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -13,7 +13,7 @@ * GNU General Public License for more details. * */ - +#include #include #include #include @@ -90,6 +90,8 @@ static int imx_drm_driv
[PATCH RFC 26/46] drivers/base: provide an infrastructure for componentised subsystems
Subsystems such as ALSA, DRM and others require a single card-level device structure to represent a subsystem. However, firmware tends to describe the individual devices and the connections between them. Therefore, we need a way to gather up the individual component devices together, and indicate when we have all the component devices. We do this in DT by providing a "superdevice" node which specifies the components, eg: imx-drm { compatible = "fsl,drm"; crtcs = <&ipu1>; connectors = <&hdmi>; }; The superdevice is declared into the component support, along with the subcomponents. The superdevice receives callbacks to locate the subcomponents, and identify when all components are present. At this point, we bind the superdevice, which causes the appropriate subsystem to be initialised in the conventional way. When any of the components or superdevice are removed from the system, we unbind the superdevice, thereby taking the subsystem down. Signed-off-by: Russell King --- drivers/base/Makefile |2 +- drivers/base/component.c | 379 + include/linux/component.h | 31 3 files changed, 411 insertions(+), 1 deletions(-) create mode 100644 drivers/base/component.c create mode 100644 include/linux/component.h diff --git a/drivers/base/Makefile b/drivers/base/Makefile index 94e8a80e87f8..870ecfd503af 100644 --- a/drivers/base/Makefile +++ b/drivers/base/Makefile @@ -1,6 +1,6 @@ # Makefile for the Linux device tree -obj-y := core.o bus.o dd.o syscore.o \ +obj-y := component.o core.o bus.o dd.o syscore.o \ driver.o class.o platform.o \ cpu.o firmware.o init.o map.o devres.o \ attribute_container.o transport_class.o \ diff --git a/drivers/base/component.c b/drivers/base/component.c new file mode 100644 index ..5492cd8d2247 --- /dev/null +++ b/drivers/base/component.c @@ -0,0 +1,379 @@ +/* + * Componentized device handling. + * + * 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 is work in progress. We gather up the component devices into a list, + * and bind them when instructed. At the moment, we're specific to the DRM + * subsystem, and only handles one master device, but this doesn't have to be + * the case. + */ +#include +#include +#include +#include +#include +#include +#include + +struct master { + struct list_head node; + struct list_head components; + bool bound; + + const struct component_master_ops *ops; + struct device *dev; +}; + +struct component { + struct list_head node; + struct list_head master_node; + struct master *master; + bool bound; + + const struct component_ops *ops; + struct device *dev; +}; + +static DEFINE_MUTEX(component_mutex); +static LIST_HEAD(component_list); +static LIST_HEAD(masters); + +static struct master *__master_find(struct device *dev, const struct component_master_ops *ops) +{ + struct master *m; + + list_for_each_entry(m, &masters, node) + if (m->dev == dev && (!ops || m->ops == ops)) + return m; + + return NULL; +} + +/* Attach an unattached component to a master. */ +static void component_attach_master(struct master *master, struct component *c) +{ + c->master = master; + + list_add_tail(&c->master_node, &master->components); +} + +/* Detach a component from a master. */ +static void component_detach_master(struct master *master, struct component *c) +{ + list_del(&c->master_node); + + c->master = NULL; +} + +int component_master_add_child(struct master *master, + int (*compare)(struct device *, void *), void *compare_data) +{ + struct component *c; + int ret = -ENXIO; + + list_for_each_entry(c, &component_list, node) { + if (c->master) + continue; + + if (compare(c->dev, compare_data)) { + component_attach_master(master, c); + ret = 0; + break; + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(component_master_add_child); + +/* Detach all attached components from this master */ +static void master_remove_components(struct master *master) +{ + while (!list_empty(&master->components)) { + struct component *c = list_first_entry(&master->components, + struct component, master_node); + + WARN_ON(c->master != master); + + component_detach_master(master, c); + } +} + +/* + * Try to bring up a master. If component is NULL, we're interested in + * this master, otherwis
[PATCH RFC 38/46] imx-drm: imx-drm-core: get rid of drm_mode_group_init_legacy_group()
Since we're now operating like a conventional DRM driver, doing all the initialisation within the driver's ->load callback, we don't need to mess around with the mode groups - we can rely on the one in the DRM platform code. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-drm-core.c |6 -- 1 files changed, 0 insertions(+), 6 deletions(-) diff --git a/drivers/staging/imx-drm/imx-drm-core.c b/drivers/staging/imx-drm/imx-drm-core.c index 7872d13689ea..10cfea0e948a 100644 --- a/drivers/staging/imx-drm/imx-drm-core.c +++ b/drivers/staging/imx-drm/imx-drm-core.c @@ -274,12 +274,6 @@ static int imx_drm_driver_load(struct drm_device *drm, unsigned long flags) drm_kms_helper_poll_init(drm); - /* setup the grouping for the legacy output */ - ret = drm_mode_group_init_legacy_group(drm, - &drm->primary->mode_group); - if (ret) - goto err_kms; - ret = drm_vblank_init(drm, MAX_CRTC); if (ret) goto err_kms; -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 14/46] imx-drm: imx-hdmi: get rid of clk manipulations in imx_hdmi_fb_registered()
The clock manipulations do nothing for us: the clock is already enabled by the only caller (imx_hdmi_platform_probe()). Get rid of these and simplify the code. Signed-off-by: Russell King --- drivers/staging/imx-drm/imx-hdmi.c |8 1 files changed, 0 insertions(+), 8 deletions(-) diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index 267d3c9114c6..1eb12c57aa3e 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -1448,12 +1448,6 @@ static int imx_hdmi_setup(struct imx_hdmi *hdmi, struct drm_display_mode *mode) /* Wait until we are registered to enable interrupts */ static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi) { - int ret; - - ret = clk_prepare_enable(hdmi->iahb_clk); - if (ret) - return ret; - hdmi_writeb(hdmi, HDMI_PHY_I2CM_INT_ADDR_DONE_POL, HDMI_PHY_I2CM_INT_ADDR); @@ -1470,8 +1464,6 @@ static int imx_hdmi_fb_registered(struct imx_hdmi *hdmi) /* Unmute interrupts */ hdmi_writeb(hdmi, ~HDMI_IH_PHY_STAT0_HPD, HDMI_IH_MUTE_PHY_STAT0); - clk_disable_unprepare(hdmi->iahb_clk); - return 0; } -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH RFC 44/46] imx-drm: dw-hdmi-audio: add audio driver
Add ALSA based HDMI audio driver for imx-hdmi. The imx-hdmi is a Synopsis DesignWare module, so let's name it after that. The only buffer format supported is its own special IEC958 based format, which is not compatible with any ALSA format. To avoid doing too much data manipulation within the driver, we support only ALSAs IEC958 LE, and 24-bit PCM formats for 2 to 6 channels. This allows us to modify the buffer in place as each period is passed for DMA without needing a separate buffer. A more desirable solution would be to have this conversion in userspace, but ALSA does not appear to allow such transformations outside of libasound itself. Signed-off-by: Russell King --- drivers/staging/imx-drm/Makefile|3 +- drivers/staging/imx-drm/dw-hdmi-audio.c | 500 +++ drivers/staging/imx-drm/dw-hdmi-audio.h | 13 + drivers/staging/imx-drm/imx-hdmi.c | 21 ++ drivers/staging/imx-drm/imx-hdmi.h |4 + 5 files changed, 540 insertions(+), 1 deletions(-) create mode 100644 drivers/staging/imx-drm/dw-hdmi-audio.c create mode 100644 drivers/staging/imx-drm/dw-hdmi-audio.h diff --git a/drivers/staging/imx-drm/Makefile b/drivers/staging/imx-drm/Makefile index 129e3a3f59f1..f554aa631993 100644 --- a/drivers/staging/imx-drm/Makefile +++ b/drivers/staging/imx-drm/Makefile @@ -1,5 +1,6 @@ imxdrm-objs := imx-drm-core.o +imxhdmi-objs := imx-hdmi.o dw-hdmi-audio.o obj-$(CONFIG_DRM_IMX) += imxdrm.o @@ -10,4 +11,4 @@ obj-$(CONFIG_DRM_IMX_IPUV3_CORE) += ipu-v3/ imx-ipuv3-crtc-objs := ipuv3-crtc.o ipuv3-plane.o obj-$(CONFIG_DRM_IMX_IPUV3)+= imx-ipuv3-crtc.o -obj-$(CONFIG_DRM_IMX_HDMI) += imx-hdmi.o +obj-$(CONFIG_DRM_IMX_HDMI) += imxhdmi.o diff --git a/drivers/staging/imx-drm/dw-hdmi-audio.c b/drivers/staging/imx-drm/dw-hdmi-audio.c new file mode 100644 index ..946055d2a975 --- /dev/null +++ b/drivers/staging/imx-drm/dw-hdmi-audio.c @@ -0,0 +1,500 @@ +/* + * DesignWare HDMI audio driver + * + * 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. + * + * Written and tested against the (alleged) DW HDMI Tx found in iMX6S. + */ +#include +#include + +#include +#include +#include +#include + +#include "imx-hdmi.h" +#include "dw-hdmi-audio.h" + +#define DRIVER_NAME "dw-hdmi-audio" + +/* Provide some bits rather than bit offsets */ +enum { + HDMI_AHB_DMA_CONF0_SW_FIFO_RST = HDMI_AHB_DMA_CONF0_SW_FIFO_RST_MASK, + HDMI_AHB_DMA_CONF0_EN_HLOCK = HDMI_AHB_DMA_CONF0_EN_HLOCK_MASK, + HDMI_AHB_DMA_START_START = BIT(HDMI_AHB_DMA_START_START_OFFSET), + HDMI_AHB_DMA_STOP_STOP = BIT(HDMI_AHB_DMA_STOP_STOP_OFFSET), + HDMI_IH_MUTE_AHBDMAAUD_STAT0_ALL = + HDMI_IH_MUTE_AHBDMAAUD_STAT0_ERROR | + HDMI_IH_MUTE_AHBDMAAUD_STAT0_LOST | + HDMI_IH_MUTE_AHBDMAAUD_STAT0_RETRY | + HDMI_IH_MUTE_AHBDMAAUD_STAT0_DONE | + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFFULL | + HDMI_IH_MUTE_AHBDMAAUD_STAT0_BUFFEMPTY, + HDMI_IH_AHBDMAAUD_STAT0_ALL = + HDMI_IH_AHBDMAAUD_STAT0_ERROR | + HDMI_IH_AHBDMAAUD_STAT0_LOST | + HDMI_IH_AHBDMAAUD_STAT0_RETRY | + HDMI_IH_AHBDMAAUD_STAT0_DONE | + HDMI_IH_AHBDMAAUD_STAT0_BUFFFULL | + HDMI_IH_AHBDMAAUD_STAT0_BUFFEMPTY, +}; + +struct snd_dw_hdmi { + struct snd_card *card; + struct snd_pcm *pcm; + void __iomem *base; + int irq; + struct imx_hdmi *hdmi; + struct snd_pcm_substream *substream; + void (*reformat)(struct snd_dw_hdmi *, size_t, size_t); + void *buf_base; + dma_addr_t buf_addr; + unsigned buf_offset; + unsigned buf_period; + unsigned buf_size; + unsigned channels; + uint8_t revision; + uint8_t iec_offset; + uint8_t cs[192][8]; +}; + +static void dw_hdmi_writeb(unsigned long val, void __iomem *ptr) +{ + writeb(val, ptr); +} + +static unsigned dw_hdmi_readb(void __iomem *ptr) +{ + return readb(ptr); +} + +static void dw_hdmi_writel(unsigned long val, void __iomem *ptr) +{ + writeb_relaxed(val, ptr); + writeb_relaxed(val >> 8, ptr + 1); + writeb_relaxed(val >> 16, ptr + 2); + writeb_relaxed(val >> 24, ptr + 3); +} + +/* + * Convert to hardware format: The userspace buffer contains IEC958 samples, + * with the PCUV bits in bits 31..28 and audio samples in bits 27..4. We + * need these to be in bits 27..24, with the IEC B bit in bit 28, and audio + * samples in 23..0. + * + * Default preamble in bits 3..0: 8 = block start, 4 = even 2 = odd + * + * Ideally, we could do with having the data properly formatted in userspace. + */ +static void dw_hdmi_reformat_iec958(struct snd_dw_hdmi *dw, + size_t offset, size_t bytes) +{ + uint32_t *ptr = dw->buf_base + offset; + uint3
[PATCH RFC 45/46] imx-drm: dw-hdmi-audio: parse ELD from HDMI driver
Parse the ELD (EDID like data) stored from the HDMI driver to restrict the sample rates and channels which are available to ALSA. This causes the ALSA device to reflect the capabilities of the overall audio path, not just what is supported at the HDMI source interface level. Signed-off-by: Russell King --- drivers/staging/imx-drm/dw-hdmi-audio.c | 50 +++ drivers/staging/imx-drm/imx-hdmi.c |8 + drivers/staging/imx-drm/imx-hdmi.h |1 + 3 files changed, 59 insertions(+), 0 deletions(-) diff --git a/drivers/staging/imx-drm/dw-hdmi-audio.c b/drivers/staging/imx-drm/dw-hdmi-audio.c index 946055d2a975..8f70e6565d22 100644 --- a/drivers/staging/imx-drm/dw-hdmi-audio.c +++ b/drivers/staging/imx-drm/dw-hdmi-audio.c @@ -274,6 +274,55 @@ static struct snd_pcm_hardware dw_hdmi_hw = { .fifo_size = 0, }; +static unsigned rates_mask[] = { + SNDRV_PCM_RATE_32000, + SNDRV_PCM_RATE_44100, + SNDRV_PCM_RATE_48000, + SNDRV_PCM_RATE_88200, + SNDRV_PCM_RATE_96000, + SNDRV_PCM_RATE_176400, + SNDRV_PCM_RATE_192000, +}; + +static void dw_hdmi_parse_eld(struct snd_dw_hdmi *dw, struct snd_pcm_runtime *runtime) +{ + uint8_t *sad, *eld = imx_hdmi_get_eld(dw->hdmi); + unsigned eld_ver, mnl, sad_count, rates, rate_mask, i; + unsigned max_channels; + + eld_ver = eld[0] >> 3; + if (eld_ver != 2 && eld_ver != 31) + return; + + mnl = eld[4] & 0x1f; + if (mnl > 16) + return; + + sad_count = eld[5] >> 4; + sad = eld + 20 + mnl; + + /* Start from the basic audio settings */ + max_channels = 2; + rates = 7; + while (sad_count > 0) { + switch (sad[0] & 0x78) { + case 0x08: /* PCM */ + max_channels = max(max_channels, (sad[0] & 7) + 1u); + rates |= sad[1]; + break; + } + sad += 3; + sad_count -= 1; + } + + for (rate_mask = i = 0; i < ARRAY_SIZE(rates_mask); i++) + if (rates & 1 << i) + rate_mask |= rates_mask[i]; + + runtime->hw.rates &= rate_mask; + runtime->hw.channels_max = min(runtime->hw.channels_max, max_channels); +} + static int dw_hdmi_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; @@ -302,6 +351,7 @@ static int dw_hdmi_open(struct snd_pcm_substream *substream) dw->base + HDMI_IH_MUTE_AHBDMAAUD_STAT0); runtime->hw = dw_hdmi_hw; + dw_hdmi_parse_eld(dw, runtime); snd_pcm_limit_hw_rates(runtime); return 0; diff --git a/drivers/staging/imx-drm/imx-hdmi.c b/drivers/staging/imx-drm/imx-hdmi.c index eb196c0862c8..949dd7c25166 100644 --- a/drivers/staging/imx-drm/imx-hdmi.c +++ b/drivers/staging/imx-drm/imx-hdmi.c @@ -375,6 +375,12 @@ void imx_hdmi_set_sample_rate(struct imx_hdmi *hdmi, unsigned int rate) } EXPORT_SYMBOL(imx_hdmi_set_sample_rate); +uint8_t *imx_hdmi_get_eld(struct imx_hdmi *hdmi) +{ + return hdmi->connector.eld; +} +EXPORT_SYMBOL(imx_hdmi_get_eld); + /* * this submodule is responsible for the video data synchronization. * for example, for RGB 4:4:4 input, the data map is defined as @@ -1406,6 +1412,8 @@ static int imx_hdmi_connector_get_modes(struct drm_connector *connector) drm_mode_connector_update_edid_property(connector, edid); ret = drm_add_edid_modes(connector, edid); + /* Store the ELD */ + drm_edid_to_eld(connector, edid); kfree(edid); } else { dev_dbg(hdmi->dev, "failed to get edid\n"); diff --git a/drivers/staging/imx-drm/imx-hdmi.h b/drivers/staging/imx-drm/imx-hdmi.h index 8029febdbabe..5baaa9cba943 100644 --- a/drivers/staging/imx-drm/imx-hdmi.h +++ b/drivers/staging/imx-drm/imx-hdmi.h @@ -1032,5 +1032,6 @@ enum { struct imx_hdmi; void imx_hdmi_set_sample_rate(struct imx_hdmi *hdmi, unsigned int rate); +uint8_t *imx_hdmi_get_eld(struct imx_hdmi *hdmi); #endif /* __IMX_HDMI_H__ */ -- 1.7.4.4 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v2] Staging: rtl8188eu: Fixed coding style issues
On 01/02/2014 02:46 PM, Tim Jester-Pfadt wrote: Fixed indentation coding style issues on rtw_io.c Signed-off-by: Tim Jester-Pfadt --- drivers/staging/rtl8188eu/core/rtw_io.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_io.c b/drivers/staging/rtl8188eu/core/rtw_io.c index 10c9c65..6be6c50 100644 --- a/drivers/staging/rtl8188eu/core/rtw_io.c +++ b/drivers/staging/rtl8188eu/core/rtw_io.c @@ -205,9 +205,9 @@ void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, - ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", - adapter->bDriverStopped, adapter->bSurpriseRemoved)); + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, + ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", + adapter->bDriverStopped, adapter->bSurpriseRemoved)); The latest version of checkpatch.pl lists the following: CHECK: Alignment should match open parenthesis #87: FILE: drivers/staging/rtl8188eu/core/rtw_io.c:207: + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, + ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", The continuing lines should be indented one more space. Larry ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[RFC PATCHv3 05/11] staging: lustre: Use is_vmalloc_addr
Instead of manually checking the bounds of VMALLOC_START and VMALLOC_END, just use is_vmalloc_addr. That's what the function was designed for. Signed-off-by: Laura Abbott --- .../staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c |3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c index 26b49a2..9364863 100644 --- a/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c +++ b/drivers/staging/lustre/lnet/klnds/o2iblnd/o2iblnd_cb.c @@ -529,8 +529,7 @@ kiblnd_kvaddr_to_page (unsigned long vaddr) { struct page *page; - if (vaddr >= VMALLOC_START && - vaddr < VMALLOC_END) { + if (is_vmalloc_addr(vaddr)) { page = vmalloc_to_page ((void *)vaddr); LASSERT (page != NULL); return page; -- The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 24/31] staging: r8188eu: Additional cleanup of include/odm.h
On 01/02/2014 03:05 AM, Dan Carpenter wrote: On Sun, Dec 22, 2013 at 05:36:55PM -0600, Larry Finger wrote: --- a/drivers/staging/rtl8188eu/include/odm_interface.h +++ b/drivers/staging/rtl8188eu/include/odm_interface.h @@ -51,7 +51,7 @@ ODM_REG(DIG,_pDM_Odm) #define _cat(_name, _ic_type, _func) \ ( \ - ((_ic_type) & ODM_IC_11N_SERIES) ? _func##_11N(_name) : \ + (_ic_type) ? _func##_11N(_name) : \ _func##_11AC(_name) \ ) The original version of this function was more readable... I think _ic_type is either zero or 16? The original driver has some code that supports many different chips; however, the present one only works for RTL8188E. In the current driver, ODM_RTL8188E is always the only bit in odm_ic_type, thus it is always 16. As a result (_ic_type & ODM_IC_11N_SERIES) is always equal to _ic_type, which is why I simplified the macro. If you really prefer the original version of the macro, I will leave it. Larry ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
BUSINESS PROPOSAL
-- Although you might be nervous about my e-mail as we have not met before. My name is Mrs Teresa Au,HSBC Hong Kong, head of corporate sustainability Asia pacific region. A sum of(USD$23,200,000.00) (Twenty three million, two Hundred Thousand dollars) Million , It is absolutely risk free,was deposited by our Late customer who died without declaring any next of kin before his death in 2006. My suggestion to you is to stand as the next of kin to Fadel Ahmed.We shall share in the ratio of 50% for me, 50% for you. Please contact me via this e- mail:mrs_te...@126.com Thanks Regards Mrs Teresa Au. ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH 31/31] staging: r8188eu: Fix smatch error
On 01/02/2014 02:44 AM, Dan Carpenter wrote: On Sun, Dec 22, 2013 at 05:37:02PM -0600, Larry Finger wrote: Smatch shows the following: CHECK drivers/staging/rtl8188eu/core/rtw_mlme_ext.c drivers/staging/rtl8188eu/core/rtw_mlme_ext.c:1401 OnAssocReq() error: buffer overflow 'pstapriv->sta_aid' 32 <= 32 This is a false positive in Smatch. Don't do work arounds for buggy tools. If you have the cross function database built on the latest version of Smatch then I think it understands the code correctly and doesn't print a warning. When I analyzed the loop in question, I thought it resulted in a subscript of [NUM_STA], but I now see that the largest one is [NUM_STA-1]. I will drop this patch in the next round. Thanks for the info regarding a new version of Smatch. I'll update now. Larry ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH v3] Staging: rtl8188eu: Fixed coding style issues
Fixed indentation coding style issues on rtw_io.c Signed-off-by: Tim Jester-Pfadt --- drivers/staging/rtl8188eu/core/rtw_io.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_io.c b/drivers/staging/rtl8188eu/core/rtw_io.c index 10c9c65..f1b8dfe 100644 --- a/drivers/staging/rtl8188eu/core/rtw_io.c +++ b/drivers/staging/rtl8188eu/core/rtw_io.c @@ -205,9 +205,9 @@ void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, - ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", - adapter->bDriverStopped, adapter->bSurpriseRemoved)); + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, +("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", +adapter->bDriverStopped, adapter->bSurpriseRemoved)); return; } _read_mem = pintfhdl->io_ops._read_mem; @@ -239,9 +239,9 @@ void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, - ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", - adapter->bDriverStopped, adapter->bSurpriseRemoved)); + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, +("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", +adapter->bDriverStopped, adapter->bSurpriseRemoved)); return; } -- 1.8.5.2 ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v3] Staging: rtl8188eu: Fixed coding style issues
On 01/02/2014 05:22 PM, Tim Jester-Pfadt wrote: Fixed indentation coding style issues on rtw_io.c Signed-off-by: Tim Jester-Pfadt --- drivers/staging/rtl8188eu/core/rtw_io.c | 12 ++-- 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/staging/rtl8188eu/core/rtw_io.c b/drivers/staging/rtl8188eu/core/rtw_io.c index 10c9c65..f1b8dfe 100644 --- a/drivers/staging/rtl8188eu/core/rtw_io.c +++ b/drivers/staging/rtl8188eu/core/rtw_io.c @@ -205,9 +205,9 @@ void _rtw_read_mem(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, - ("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", - adapter->bDriverStopped, adapter->bSurpriseRemoved)); + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, +("rtw_read_mem:bDriverStopped(%d) OR bSurpriseRemoved(%d)", +adapter->bDriverStopped, adapter->bSurpriseRemoved)); return; } _read_mem = pintfhdl->io_ops._read_mem; @@ -239,9 +239,9 @@ void _rtw_read_port(struct adapter *adapter, u32 addr, u32 cnt, u8 *pmem) _func_enter_; if (adapter->bDriverStopped || adapter->bSurpriseRemoved) { -RT_TRACE(_module_rtl871x_io_c_, _drv_info_, - ("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", - adapter->bDriverStopped, adapter->bSurpriseRemoved)); + RT_TRACE(_module_rtl871x_io_c_, _drv_info_, +("rtw_read_port:bDriverStopped(%d) OR bSurpriseRemoved(%d)", +adapter->bDriverStopped, adapter->bSurpriseRemoved)); return; } Acked-by: Larry Finger Thanks, Larry ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
[PATCH] Staging: rtl8188eu: Fixed spaces before tabs and before close parentheses
Fixed all space before tab warnings and space before close parenthesis errors on rtl8188e_spec.h Signed-off-by: Tim Jester-Pfadt --- drivers/staging/rtl8188eu/include/rtl8188e_spec.h | 70 +++ 1 file changed, 35 insertions(+), 35 deletions(-) diff --git a/drivers/staging/rtl8188eu/include/rtl8188e_spec.h b/drivers/staging/rtl8188eu/include/rtl8188e_spec.h index c12c56b9..2c33eb3 100644 --- a/drivers/staging/rtl8188eu/include/rtl8188e_spec.h +++ b/drivers/staging/rtl8188eu/include/rtl8188e_spec.h @@ -68,7 +68,7 @@ #define DISABLE_TRXPKT_BUF_ACCESS 0x0 -/* 0xh ~ 0x00FFh System Configuration */ +/* 0xh ~ 0x00FFh System Configuration */ #define REG_SYS_ISO_CTRL 0x #define REG_SYS_FUNC_EN0x0002 #define REG_APS_FSMCO 0x0004 @@ -142,7 +142,7 @@ #define REG_MAC_PHY_CTRL_NORMAL0x00f8 -/* 0x0100h ~ 0x01FFh MACTOP General Configuration */ +/* 0x0100h ~ 0x01FFh MACTOP General Configuration */ #define REG_CR 0x0100 #define REG_PBP0x0104 #define REG_PKT_BUFF_ACCESS_CTRL 0x0106 @@ -188,7 +188,7 @@ #define REG_LLT_INIT 0x01E0 -/* 0x0200h ~ 0x027Fh TXDMA Configuration */ +/* 0x0200h ~ 0x027Fh TXDMA Configuration */ #define REG_RQPN 0x0200 #define REG_FIFOPAGE 0x0204 #define REG_TDECTRL0x0208 @@ -196,12 +196,12 @@ #define REG_TXDMA_STATUS 0x0210 #define REG_RQPN_NPQ 0x0214 -/* 0x0280h ~ 0x02FFh RXDMA Configuration */ +/* 0x0280h ~ 0x02FFh RXDMA Configuration */ #defineREG_RXDMA_AGG_PG_TH 0x0280 #defineREG_RXPKT_NUM 0x0284 #defineREG_RXDMA_STATUS0x0288 -/* 0x0300h ~ 0x03FFh PCIe */ +/* 0x0300h ~ 0x03FFh PCIe */ #defineREG_PCIE_CTRL_REG 0x0300 #defineREG_INT_MIG 0x0304 /* Interrupt Migration */ #defineREG_BCNQ_DESA 0x0308 /* TX Beacon Descr Address */ @@ -222,7 +222,7 @@ #defineREG_PCIE_HISR 0x03A0 /* spec version 11 */ -/* 0x0400h ~ 0x047Fh Protocol Configuration */ +/* 0x0400h ~ 0x047Fh Protocol Configuration */ #define REG_VOQ_INFORMATION0x0400 #define REG_VIQ_INFORMATION0x0404 #define REG_BEQ_INFORMATION0x0408 @@ -276,7 +276,7 @@ #define REG_TX_RPT_TIME0x04F0 /* 2 byte */ #define REG_DUMMY 0x04FC -/* 0x0500h ~ 0x05FFh EDCA Configuration */ +/* 0x0500h ~ 0x05FFh EDCA Configuration */ #define REG_EDCA_VO_PARAM 0x0500 #define REG_EDCA_VI_PARAM 0x0504 #define REG_EDCA_BE_PARAM 0x0508 @@ -294,16 +294,16 @@ #define REG_DIS_TXREQ_CLR 0x0523 #define REG_RD_CTRL0x0524 /* Format for offset 540h-542h: */ -/* [3:0]: TBTT prohibit setup in unit of 32us. The time for HW getting +/* [3:0]: TBTT prohibit setup in unit of 32us. The time for HW getting * beacon content before TBTT. */ -/* [7:4]: Reserved. */ -/* [19:8]: TBTT prohibit hold in unit of 32us. The time for HW holding +/* [7:4]: Reserved. */ +/* [19:8]: TBTT prohibit hold in unit of 32us. The time for HW holding * to send the beacon packet. */ -/* [23:20]: Reserved */ +/* [23:20]: Reserved */ /* Description: */ -/* | */ +/* | */ /* |<--Setup--|--Hold>| */ -/* --|-- */ +/* --|-- */ /* | */ /*TBTT */ /* Note: We cannot update beacon content to HW or send any AC packets during @@ -335,7 +335,7 @@ #define REG_FW_RESET_TSF_CNT_0 0x05FD #define REG_FW_BCN_DIS_CNT 0x05FE -/* 0x0600h ~ 0x07FFh WMAC Configuration */ +/* 0x0600h ~ 0x07FFh WMAC Configuration */ #define REG_APSD_CTRL 0x0600 #define REG_BWOPMODE 0x0603 #define REG_TCR0x0604 @@ -382,7 +382,7 @@ #define _RXERR_RPT_SEL(type) ((type) << 28) /* Note: */ -/* The NAV upper value is very important to WiFi 11n 5.2.3 NAV test. +/* The NAV upper value is very important to WiFi 11n 5.2.3 NAV test. * The default value is always too small, but the WiFi TestPlan test * by 25,000 microseconds of NAV through sending CTS in the air. * We must update this value greater than 25,000 microseconds to pass @@ -422,7 +422,7 @@ #define REG_MACID1 0x0700 #define REG_BSSID1 0x0708 -/* 0xFE00h ~ 0xFE55h USB Configuratio
Re: [PATCH RFC 26/46] drivers/base: provide an infrastructure for componentised subsystems
On Thu, Jan 02, 2014 at 09:27:58PM +, Russell King wrote: > Subsystems such as ALSA, DRM and others require a single card-level > device structure to represent a subsystem. However, firmware tends to > describe the individual devices and the connections between them. > > Therefore, we need a way to gather up the individual component devices > together, and indicate when we have all the component devices. > > We do this in DT by providing a "superdevice" node which specifies > the components, eg: > > imx-drm { > compatible = "fsl,drm"; > crtcs = <&ipu1>; > connectors = <&hdmi>; > }; > > The superdevice is declared into the component support, along with the > subcomponents. The superdevice receives callbacks to locate the > subcomponents, and identify when all components are present. At this > point, we bind the superdevice, which causes the appropriate subsystem > to be initialised in the conventional way. > > When any of the components or superdevice are removed from the system, > we unbind the superdevice, thereby taking the subsystem down. This sounds a lot like the "containers" code that Rafael just submitted and I acked for 3.14. Look at the lkml post: Subject: [PATCH 2/2] ACPI / hotplug / driver core: Handle containers in a special way Message-ID: <1991202.gilw172...@vostro.rjw.lan> And see if that could possibly be used instead? thanks, greg k-h ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel
Re: [PATCH v3] Staging: rtl8188eu: Fixed coding style issues
On Fri, Jan 03, 2014 at 12:22:59AM +0100, Tim Jester-Pfadt wrote: > Fixed indentation coding style issues on rtw_io.c > > Signed-off-by: Tim Jester-Pfadt > --- Next time, if you do a v2 patch please put a note here under the --- line what changed between the previous one and this one. 2: changed blah blah blah. > drivers/staging/rtl8188eu/core/rtw_io.c | 12 ++-- > 1 file changed, 6 insertions(+), 6 deletions(-) regards, dan carpenter ___ devel mailing list de...@linuxdriverproject.org http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel