2024-09-09 08:57:42 +00:00
|
|
|
#ifdef CONFIG_ARCH_MSM7X27A
|
|
|
|
#include <mach/rpc_pmapp.h>
|
|
|
|
#else
|
2024-09-09 08:52:07 +00:00
|
|
|
#include <linux/device.h>
|
|
|
|
#include <linux/regulator/consumer.h>
|
2024-09-09 08:57:42 +00:00
|
|
|
#include <linux/gpio.h>
|
|
|
|
#include <linux/err.h>
|
2024-09-09 08:52:07 +00:00
|
|
|
#include <linux/platform_device.h>
|
2024-09-09 08:57:42 +00:00
|
|
|
/* replace with plaftform specific changes */
|
|
|
|
#endif
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
#include "core.h"
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
/* BeginMMC polling stuff */
|
|
|
|
#ifdef CONFIG_ARCH_MSM7X27A
|
|
|
|
#define MMC_PLATFORM_DEV "msm_sdcc.2"
|
|
|
|
#else
|
|
|
|
#define MMC_PLATFORM_DEV "sdcc"
|
|
|
|
#endif
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
/* End MMC polling stuff */
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
#define GET_INODE_FROM_FILEP(filp) \
|
|
|
|
((filp)->f_path.dentry->d_inode)
|
2024-09-09 08:52:07 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
#define ATH6KL_INIT_TIMEOUT (6 * HZ)
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
wait_queue_head_t init_wq;
|
|
|
|
static atomic_t init_done = ATOMIC_INIT(0);
|
2024-09-09 08:52:07 +00:00
|
|
|
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
int android_readwrite_file(const char *filename,
|
|
|
|
char *rbuf, const char *wbuf, size_t length)
|
2024-09-09 08:52:07 +00:00
|
|
|
{
|
2024-09-09 08:57:42 +00:00
|
|
|
int ret = 0;
|
|
|
|
struct file *filp = (struct file *)-ENOENT;
|
|
|
|
mm_segment_t oldfs;
|
|
|
|
oldfs = get_fs();
|
|
|
|
set_fs(KERNEL_DS);
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
do {
|
|
|
|
int mode = (wbuf) ? O_RDWR : O_RDONLY;
|
|
|
|
filp = filp_open(filename, mode, S_IRUSR);
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
if (IS_ERR(filp) || !filp->f_op) {
|
|
|
|
ret = -ENOENT;
|
|
|
|
break;
|
2024-09-09 08:52:07 +00:00
|
|
|
}
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
if (length == 0) {
|
|
|
|
/* Read the length of the file only */
|
|
|
|
struct inode *inode;
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
inode = GET_INODE_FROM_FILEP(filp);
|
|
|
|
if (!inode) {
|
|
|
|
printk(KERN_ERR "android_readwrite_file: Error 2\n");
|
|
|
|
ret = -ENOENT;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ret = i_size_read(inode->i_mapping->host);
|
|
|
|
break;
|
2024-09-09 08:52:07 +00:00
|
|
|
}
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
if (wbuf) {
|
|
|
|
ret = filp->f_op->write(filp, wbuf, length, &filp->f_pos);
|
|
|
|
if (ret < 0) {
|
|
|
|
printk(KERN_ERR
|
|
|
|
"android_readwrite_file: Error 3\n");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
ret = filp->f_op->read(filp, rbuf, length, &filp->f_pos);
|
|
|
|
if (ret < 0) {
|
|
|
|
printk(KERN_ERR
|
|
|
|
"android_readwrite_file: Error 4\n");
|
|
|
|
break;
|
|
|
|
}
|
2024-09-09 08:52:07 +00:00
|
|
|
}
|
2024-09-09 08:57:42 +00:00
|
|
|
} while (0);
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
if (!IS_ERR(filp))
|
|
|
|
filp_close(filp, NULL);
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
set_fs(oldfs);
|
|
|
|
printk(KERN_ERR "android_readwrite_file: ret=%d\n", ret);
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
return ret;
|
2024-09-09 08:52:07 +00:00
|
|
|
}
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
static int ath6kl_pm_probe(struct platform_device *pdev)
|
2024-09-09 08:52:07 +00:00
|
|
|
{
|
2024-09-09 08:57:42 +00:00
|
|
|
#ifdef CONFIG_ARCH_MSM7X27A
|
|
|
|
int (*plat_setup_power)(int on);
|
|
|
|
plat_setup_power = pdev->dev.platform_data;
|
|
|
|
printk(KERN_ERR "%s () enter and will invoke power-up sequence\n",
|
|
|
|
__func__);
|
|
|
|
if (plat_setup_power)
|
|
|
|
plat_setup_power(1);
|
|
|
|
#else
|
|
|
|
/* replace with plaftform specific changes */
|
|
|
|
#endif
|
|
|
|
return 0;
|
2024-09-09 08:52:07 +00:00
|
|
|
}
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
static int ath6kl_pm_remove(struct platform_device *pdev)
|
2024-09-09 08:52:07 +00:00
|
|
|
{
|
2024-09-09 08:57:42 +00:00
|
|
|
#ifdef CONFIG_ARCH_MSM7X27A
|
|
|
|
int (*plat_setup_power)(int on);
|
|
|
|
plat_setup_power = pdev->dev.platform_data;
|
|
|
|
printk(KERN_ERR "%s () enter and will invoke power-down sequence\n",
|
|
|
|
__func__);
|
|
|
|
if (plat_setup_power)
|
|
|
|
plat_setup_power(0);
|
|
|
|
#else
|
|
|
|
/* replace with plaftform specific changes */
|
|
|
|
#endif
|
|
|
|
return 0;
|
2024-09-09 08:52:07 +00:00
|
|
|
}
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
static int ath6kl_pm_suspend(struct platform_device *pdev, pm_message_t state)
|
2024-09-09 08:52:07 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
static inline void *ar6k_priv(struct net_device *dev)
|
2024-09-09 08:52:07 +00:00
|
|
|
{
|
2024-09-09 08:57:42 +00:00
|
|
|
return wdev_priv(dev->ieee80211_ptr);
|
2024-09-09 08:52:07 +00:00
|
|
|
}
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
static int ath6kl_pm_resume(struct platform_device *pdev)
|
2024-09-09 08:52:07 +00:00
|
|
|
{
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
static struct platform_driver ath6kl_pm_device = {
|
|
|
|
.probe = ath6kl_pm_probe,
|
|
|
|
.remove = ath6kl_pm_remove,
|
|
|
|
.suspend = ath6kl_pm_suspend,
|
|
|
|
.resume = ath6kl_pm_resume,
|
|
|
|
.driver = {
|
|
|
|
.name = "wlan_ar6000_pm_dev",
|
2024-09-09 08:52:07 +00:00
|
|
|
},
|
|
|
|
};
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
int __init ath6kl_sdio_init_platform(void)
|
2024-09-09 08:52:07 +00:00
|
|
|
{
|
2024-09-09 08:57:42 +00:00
|
|
|
char buf[3];
|
|
|
|
int length, ret;
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
ret = platform_driver_register(&ath6kl_pm_device);
|
|
|
|
if (ret) {
|
|
|
|
printk(KERN_ERR "platform driver registration failed: %d\n",
|
|
|
|
ret);
|
|
|
|
return ret;
|
2024-09-09 08:52:07 +00:00
|
|
|
}
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
length = snprintf(buf, sizeof(buf), "%d\n", 1 ? 1 : 0);
|
|
|
|
android_readwrite_file("/sys/devices/platform/" MMC_PLATFORM_DEV
|
|
|
|
"/polling", NULL, buf, length);
|
|
|
|
length = snprintf(buf, sizeof(buf), "%d\n", 0 ? 1 : 0);
|
|
|
|
android_readwrite_file("/sys/devices/platform/" MMC_PLATFORM_DEV
|
|
|
|
"/polling", NULL, buf, length);
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
mdelay(50);
|
2024-09-09 08:52:07 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
void ath6kl_sdio_exit_platform(void)
|
2024-09-09 08:52:07 +00:00
|
|
|
{
|
2024-09-09 08:57:42 +00:00
|
|
|
char buf[3];
|
2024-09-09 08:52:07 +00:00
|
|
|
int length;
|
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
platform_driver_unregister(&ath6kl_pm_device);
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
length = snprintf(buf, sizeof(buf), "%d\n", 1 ? 1 : 0);
|
|
|
|
/* fall back to polling */
|
|
|
|
android_readwrite_file("/sys/devices/platform/" MMC_PLATFORM_DEV
|
|
|
|
"/polling", NULL, buf, length);
|
|
|
|
length = snprintf(buf, sizeof(buf), "%d\n", 0 ? 1 : 0);
|
|
|
|
/* fall back to polling */
|
|
|
|
android_readwrite_file("/sys/devices/platform/" MMC_PLATFORM_DEV
|
|
|
|
"/polling", NULL, buf, length);
|
|
|
|
mdelay(1000);
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
}
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
int ath6kl_wait_for_init_comp(void)
|
|
|
|
{
|
|
|
|
int left, ret = 0;
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
if (atomic_read(&init_done) == 1)
|
|
|
|
return ret;
|
2024-09-09 08:52:07 +00:00
|
|
|
|
2024-09-09 08:57:42 +00:00
|
|
|
left = wait_event_interruptible_timeout(init_wq,
|
|
|
|
atomic_read(&init_done) == 1,
|
|
|
|
ATH6KL_INIT_TIMEOUT);
|
|
|
|
if (left == 0) {
|
|
|
|
printk(KERN_ERR "timeout while waiting for init operation\n");
|
|
|
|
ret = -ETIMEDOUT;
|
|
|
|
} else if (left < 0) {
|
|
|
|
printk(KERN_ERR "wait for init operation failed: %d\n", left);
|
|
|
|
ret = left;
|
2024-09-09 08:52:07 +00:00
|
|
|
}
|
2024-09-09 08:57:42 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
void ath6kl_notify_init_done(void)
|
|
|
|
{
|
|
|
|
atomic_set(&init_done, 1);
|
|
|
|
wake_up(&init_wq);
|
2024-09-09 08:52:07 +00:00
|
|
|
}
|