Wednesday, December 8, 2010

Some Common Questions?

1) What is unaligned memory access?

Definition:
Unaligned memory accesses occur when you try to read N bytes of
data starting from an address that is not evenly divisible by N
(i.e. addr % N != 0). For example, reading 4 bytes of data
from address 0x10004 is fine, but reading 4 bytes of data from
address 0x10005 would be an unaligned memory access.

Fortunately things are not too complex, as in most cases, the
compiler ensures that things will work for you.

For more reading,
http://lwn.net/Articles/260456/

Thursday, December 2, 2010

A moment of pride

This is really a moment of pride for me. My driver is going upstream mainline Linux kernel.

Here it goes, the mail from Takashi Iwai to Linus Torvalds requesting to pull the driver,


One of my dreams comes true... Aha.....
I love Linux kernel. The way it works... During initial days of my career I used to ask many questions in the mailing list. I was amazed with the support and patience they posses. So I decided one day I will give something back to the community.

Contributions

Arun

Thursday, November 18, 2010

Minimal git commands

Initialize a repository by,

git init

Add files to the repo by,

git add .

git add file

removal,
git rm file

rename,
git mv old new

This will add all the file under the directory recursively.

Now do a base commit,

git commit -a

This will commit all the files to the repository .

To create a new branch for editing,
git checkout -b devel

Commit only required changes
If you have many changes, for example in folders like drivers/video and drivers/sound. And you only want to commit the changes to drivers/video, then git add those files and type git commit without using -a option.

git add drivers/video/
git commit

If your master has grown beyond the point when you took the devel branch, you can update the master and you can rebase the devel branch to master,

git rebase -i master

Have a look here for more doubts about merging issues.
http://stackoverflow.com/questions/449541/how-do-you-merge-selective-files-with-git-merge

configuring the .gitconfig file,
My .gitconfig file looks like this
cat ~/.gitconfig
[user]
name = "Arun Sudhilal"
email = "arun.sudhilal@lntinfotech.com"
[core]
editor = vim
[color]
ui = auto
[merge]
tool = vimdiff

Creating patches,
git format-patch HEAD~1

HEAD^^ == HEAD~2


---
git show
git show --stat
git show --name-status HEAD~3
git show HEAD:file
contents.....

git log
git log HEAD~10..

git log --author=arun
git log --committer=arun
git log --grep="commit.*message.*text"

For expample if i want to grep "frame", then
git log --grep="grame"
git log -S "some code change"
git log file
git grep -e "pattern" -- some/file

git branch name commit
git checkout name
git checkout -b name commit
git checkout -m name
merge outstanding diff onto branch "name", can result in conflict.

git tag -a -m "got somewhere" good

git rebase
moves new work to a new base line

git fetch
Just update the remote, but doesn't update work space

git fetch + git merge = git pull

to apply a patch in you local tree,
git am -3

Pushing to the repositories,
* git push origin will push changes from all local branches to matching branches the origin remote
* git push origin master will push changes from the local master branch to the remote master branch
* git push origin master:staginwill push changes from the local master branch to the remote staging branch if it exists

Recovering lost commits,Sometime by mistake you might have done git reset --hard HEAD^. Then you realise that you need that commit. Dont worry, git has a way to recover your lost commit.

git reflog

Git tracks almost everything you does. If you feels that you have screwed up you repo by rebase, merge or even by reset, you can dig reflog and get it back.

git reflog output may be something like this,
6d2a85e HEAD@{0}: merge 6d2a85e: Fast-forward
28eb495 HEAD@{1}: 28eb49561313ce479f228acea6d25a2bf20166a8: updating HEAD
6d2a85e HEAD@{2}: pull : Fast-forward
6744afe HEAD@{3}: 6744afe5afa033763cdb4e698eea1a5febabae8e: updating HEAD

once you get this you can check with git show which commit you want. For here you can cherry-pic, merge or checkout.


.gitconfig
And this is how my .gitconfig looks like,



Renaming current branch,
git branch -m linux-linaro-tracking

Checkout with the same name as remote,
git co -t remotes/origin/linux-linaro

Suwon, S Korea

Monday, November 8, 2010

Touch doesnt work in lock screen after resuming from sleep

In file drivers/i2c/busses/i2c-s3c2410.c, function,
static int s3c24xx_i2c_set_master(struct s3c24xx_i2c *i2c)
{
unsigned long iicstat;
int timeout = 400;

while (timeout-- > 0) {
iicstat = readl(i2c->regs + S3C2410_IICSTAT);

if (!(iicstat & S3C2410_IICSTAT_BUSBUSY))
return 0;

msleep(1);
}

return -ETIMEDOUT;
}

Some how the bus is busy even after 400 iterations. The i2c adaptor may be going to some invalid state. Added,

writel(iicstat & ~S3C2410_IICSTAT_TXRXEN, i2c->regs + S3C2410_IICSTAT);

after the msleep(1). This will disable the Rx/Tx of the i2c adapter, which is later enabled. So basically its a reset of the register

I2C-bus data output enable/ disable bit.
0 = Disables Rx/Tx,
1 = Enables Rx/Tx

This blog looks interesting about the i2c drive in linux-2.6.32
http://www.embedded-bits.co.uk/?p=174

Saturday, November 6, 2010

wakeup from suspend to Ram

echo mem > /sys/power/state should suspend to ram and
echo on > /sys/power/state should wake up the device from suspend.

Former was not working on Atlas phone. It was because the read from /sys/power/state was not implemented properly. When you try to read it should print all the valid power states. But it was only giving mem as the output. In file kernel/power/main.c, function state_show calls valid_states which in turn calls a architecture implemented function pointer. The function is called by passing mem, on or standby as the argument. It will return true if it architecture support the argument state. So state_show will give out put accordingly.

Previously it was giving true only for mem. Modified the .valid function pointer in the architecutre file (arch/arm/plat-samsung/pm.c) to give true for mem, on and standby. This fixed the wakeup issue.

Got some help from,
Linux Symposium

Monday, October 18, 2010

Adding send end key as a wake-up source

On MSM chip there are three Interrupt controllers. One for ARM11, one for ARM9 and one dedicated Interrupt controller(Simple Interrupt Controller(SIC), this is always on) to work when both processors sleep. So before ARM11 sleeps we have to send the wake-up irqs to CP. So that MPP IC will monitors only those wake-up interrupts send by AP. This is achieved by using the kernel function enalbe_irq_wake(irq no). This will add the flag IRQ_WAKE to that descriptor of that particular irq. So whenever AP go to sleep it will send this irq number also to the CP as a wake-up soruce.

Tuesday, September 14, 2010

Problem with udelay

I was working on a mobile device, reducing lcd wake up time once powerkey is pressed. In LCD driver there were many msleeps() used in the kernel. There is some structure like this.

Struct lcd_startup_sequence {
U16 cmd;
U16 timeout;/*in ms*/
}

lcd_startup_sequence[10] = {
{0x34, 100},
{0x23, 0},
{0x14, 0},
{0x11, 50},
};

What i did first is this,

if(lcd_starup_sequence.delay)
msleep(lcd_startup_swquence.delay);

So this will avoids the calls from msleep(0); Because even if msleep is called with 0 as the argument, the current thread will be kept on the wait queue from the running queue.

But from this I haven't got much improvement. So I thought of changing msleep() to mdelay(). So it takes the correct time, because it is busy waiting than sleeping. But you should be very careful in using mdelay() because you are just eating up the processor time. So if not necessary use msleep() instead. This give me good improvement.

The funny part is that in another place also I changed from msleep(100) to mdelay(100). Surprisingly here mdelay is taking around 200 ms and msleep is taking 110 ms. What the heck?
Then I digged in the kernel and found plenty of information about kernel time keeping. The following link explaing how the delay is generated in linux kernel:
http://kerneltrap.org/node/6857

But the reason for mdelay behavior is explained below:
udelay() can be incorrect on SMP machines that scale their CPU frequencies independently of one another he delay loop can either be too fast or too slow depending on which CPU the loops_per_jiffy counter is calibrated on and which CPU the delay loop is running on. udelay() can also be incorrect if the CPU frequency switches during the __delay() loop, causing the loop
to either terminate too early, or too late.

For more informations:
http://www.spinics.net/lists/linux-arm-msm/msg00208.html
http://groups.google.co.kr/group/linux.kernel/browse_thread/thread/0a5c1395e82eabc2?pli=1